VueJS - 事件
Vue 3 - 事件处理
Section titled “Vue 3 - 事件处理”Vue 允许你使用 v-on 指令(或其简写形式 @)来监听 DOM 事件,并在这些事件触发时运行 JavaScript 代码。本章将介绍 Vue 3 中事件处理的各个方面。
监听事件 (v-on 或 @)
Section titled “监听事件 (v-on 或 @)”你可以使用 v-on:eventname 或简写形式 @eventname 来为元素附加事件监听器。
示例:点击事件
Section titled “示例:点击事件”<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Vue 3 Click Event</title> <script src="https://unpkg.com/vue@3"></script></head><body> <div id="app-click"> <button v-on:click="incrementCounter">Click Me (v-on)</button> <button @click="incrementCounter">Click Me (@)</button> <p>Counter: {{ counter }}</p> <button @click="greet('Hello Vue!')">Greet</button> </div>
<script> const { createApp, ref } = Vue;
createApp({ setup() { const counter = ref(0);
function incrementCounter() { counter.value++; console.log('Counter incremented!'); }
function greet(message) { alert(message); }
return { counter, incrementCounter, greet }; } }).mount('#app-click'); </script></body></html>v-on:click="incrementCounter"或@click="incrementCounter"在点击按钮时调用incrementCounter方法。- 在 Composition API 中,方法定义在
setup()函数内部。 - 你可以直接在模板中传递参数,例如
@click="greet('Hello Vue!')"。 - 如果你需要访问原始的 DOM 事件对象,在没有传递其他参数时,你可以自动接收它(
incrementCounter可以接受event作为其第一个参数);或者通过特殊的$event变量显式传递它:@click="handleEvent($event, 'some value')"。
示例:鼠标事件 (mouseover, mouseout)
Section titled “示例:鼠标事件 (mouseover, mouseout)”<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Vue 3 Mouse Events</title> <script src="https://unpkg.com/vue@3"></script> <style> .hover-box { width: 150px; height: 100px; border: 1px solid black; display: flex; justify-content: center; align-items: center; cursor: pointer; transition: background-color 0.3s ease; } </style></head><body> <div id="app-mouse"> <div class="hover-box" :style="{ backgroundColor: boxColor }" @mouseover="changeColor('lightgreen')" @mouseout="changeColor('lightblue')"> Hover over me! </div> <p>Current Box Color: {{ boxColor }}</p> </div>
<script> const { createApp, ref } = Vue;
createApp({ setup() { const boxColor = ref('lightblue'); // Initial color
function changeColor(newColor) { boxColor.value = newColor; }
return { boxColor, changeColor }; } }).mount('#app-mouse'); </script></body></html>- 该
div监听mouseover和mouseout事件。 - 事件发生时,会调用
changeColor方法,并传入所需的颜色字符串。 - 背景颜色使用
:style动态绑定到boxColor这个 reactive (响应式)变量上。
Vue 提供了事件修饰符,用于直接在模板中处理一些常见的任务。修饰符是添加在事件名称后面的后缀,用点 (.) 分隔:
.stop: 调用event.stopPropagation()。.prevent: 调用event.preventDefault()。.capture: 在捕获模式下添加事件监听器。.self: 只有当事件是从该元素自身触发时才触发处理函数(而不是来自子元素)。.once: 处理函数最多触发一次。.passive: 提高移动设备上滚动事件的性能(对应于addEventListener的passive选项)。
示例:.prevent 和 .once
Section titled “示例:.prevent 和 .once”<div id="app-modifiers"> <!-- Prevent default form submission --> <form @submit.prevent="onSubmit"> <input type="text" placeholder="Enter something"> <button type="submit">Submit (No Page Reload)</button> </form>
<!-- Button that can only be clicked once --> <button @click.once="doOnce">Click Me Only Once</button> <p>Once Click Count: {{ onceCount }}</p></div>
<script> const { createApp, ref } = Vue; createApp({ setup() { const onceCount = ref(0); function onSubmit() { alert('Form submitted via Vue (page did not reload)!'); } function doOnce() { onceCount.value++; alert('This alert appears only once!'); } return { onSubmit, doOnce, onceCount }; } }).mount('#app-modifiers');</script>.prevent 阻止表单的默认提交行为(页面刷新)。.once 确保 doOnce 方法只在按钮第一次被点击时调用。
Vue 允许你使用按键修饰符,仅当用户按下特定按键时才触发事件处理函数。
.enter.tab.delete(捕获 ‘Delete’ 和 ‘Backspace’ 键).esc.space.up,.down,.left,.right(方向键)- 系统修饰符:
.ctrl,.alt,.shift,.meta(Mac 上的 Command 键,Windows 上的 Windows 键)
示例:.enter 按键修饰符
Section titled “示例:.enter 按键修饰符”<div id="app-keys"> <label>Submit on Enter:</label> <input type="text" v-model="message" @keyup.enter="submitMessage" placeholder="Type and press Enter"> <p>Submitted: {{ submittedMessage }}</p></div>
<script> const { createApp, ref } = Vue; createApp({ setup() { const message = ref(''); const submittedMessage = ref(''); function submitMessage() { submittedMessage.value = message.value; message.value = ''; // Clear input alert('Message submitted!'); } return { message, submittedMessage, submitMessage }; } }).mount('#app-keys');</script>只有当用户在输入框中按下并释放 ‘Enter’ 键时,才会调用 submitMessage 方法。
自定义事件(子组件向父组件通信)
Section titled “自定义事件(子组件向父组件通信)”组件可以使用 $emit 方法触发自定义事件。父组件可以使用 v-on 或 @ 监听这些事件。
示例:触发自定义事件
Section titled “示例:触发自定义事件”<div id="app-custom-event"> <p>Selected Language: {{ selectedLanguage || 'None' }}</p> <!-- Child component emitting 'language-selected' event --> <language-selector :languages="availableLanguages" @language-selected="handleLanguageSelection"> </language-selector></div>
<script> const { createApp, ref } = Vue;
const app = createApp({ setup() { const selectedLanguage = ref(''); const availableLanguages = ref(['JavaScript', 'Python', 'Java', 'C#']);
function handleLanguageSelection(language) { selectedLanguage.value = language; console.log(`Parent received selected language: ${language}`); }
return { selectedLanguage, availableLanguages, handleLanguageSelection }; } });
// Child Component: LanguageSelector app.component('language-selector', { props: { languages: { type: Array, required: true } }, emits: ['language-selected'], // 最佳实践:声明要触发的事件 template: ` <div> <button v-for="lang in languages" :key="lang" @click="selectLanguage(lang)" style="margin: 5px; font-size: 1em;"> {{ lang }} </button> </div> `, methods: { selectLanguage(lang) { // 触发事件,并将选中的语言作为载荷(payload)传递 this.$emit('language-selected', lang); } } // 在组件的 Composition API setup 函数中: /* setup(props, { emit }) { function selectLanguage(lang) { emit('language-selected', lang); } return { selectLanguage }; } */ });
app.mount('#app-custom-event');</script>language-selector子组件通过 props 接收语言列表。- 当子组件中的按钮被点击时,其
selectLanguage方法会调用this.$emit('language-selected', lang)。这会将language-selected事件向上发送给父组件,并将选定的语言 (lang) 作为数据 (载荷/payload) 传递。 - 父组件使用
@language-selected="handleLanguageSelection"在<language-selector>标签上监听此事件。 - 父组件的
handleLanguageSelection方法接收到载荷(选定的语言)并更新selectedLanguage状态。 - 在子组件中使用
emits: ['language-selected']声明要触发的事件,这是 Vue 3 中推荐的做法,可以提高代码清晰度并可能带来未来的优化。
事件处理是构建交互式应用的基础。Vue 的系统,包括 v-on、修饰符和 $emit,提供了一种强大且声明式的方式来管理用户交互和组件通信。