Vue2和Vue3在事件修饰符上的主要区别在于.native修饰符的处理。
Vue2需要通过.native修饰符监听组件根元素的原生事件,而Vue3默认监听原生事件,只有当组件使用emits选项声明时才转为自定义事件。
其他常用修饰符(如.stop、.prevent等)在两个版本中功能一致。
Vue3移除了.native修饰符,简化了组件事件处理逻辑,使默认行为更符合直觉。
修饰符的链式调用方式在Vue2和Vue3中都保持相同。
Vue 2 和 Vue 3 事件修饰符对比
.native 修饰符
.native 修饰符用于在组件上直接监听原生 DOM 事件。
为什么需要它?
默认情况下,在 Vue 组件上使用 @click 等事件监听的是组件自定义事件 (通过 $emit 触发),而不是原生 DOM 事件。
html
<!-- 这样写,监听的是组件内部 $emit('click') 触发的自定义事件 -->
<MyComponent @click="handleClick" />
使用 .native
添加 .native 修饰符后,会直接监听组件根元素的原生事件:
html
<!-- 现在监听的是组件根元素的原生 click 事件 -->
<MyComponent @click.native="handleClick" />
实际示例
html
<!-- 父组件 -->
<template>
<div>
<!-- 不会触发:Button 组件没有 $emit('click') -->
<Button @click="handleClick1" />
<!-- 会触发:监听 Button 根元素的原生 click -->
<Button @click.native="handleClick2" />
</div>
</template>
<script>
import Button from './Button.vue'
export default {
components: { Button },
methods: {
handleClick1() { console.log('不会执行') },
handleClick2() { console.log('原生点击触发') }
}
}
</script>
Vue 3 的变化
Vue 3 中移除了 .native 修饰符 。现在组件上所有事件监听都被视为原生事件,除非组件内部使用 emits 选项显式声明为自定义事件:
html
<!-- Vue 3:默认就是原生事件 -->
<MyComponent @click="handleClick" />
<!-- 如果组件声明了 emits: ['click'],则 click 变为自定义事件 -->
<script setup>
// 声明后,@click 变为监听自定义事件
const emit = defineEmits(['click'])
</script>
总结
| 版本 | 用法 | 说明 |
|---|---|---|
| Vue 2 | @click.native |
需要显式添加修饰符 |
| Vue 3 | @click |
默认原生,声明 emits 后变自定义 |
Vue 2 和 Vue 3 事件修饰符对比
| 修饰符 | Vue 2 | Vue 3 | 说明 |
|---|---|---|---|
.stop |
✅ | ✅ | 阻止事件冒泡,调用 event.stopPropagation() |
.prevent |
✅ | ✅ | 阻止默认行为,调用 event.preventDefault() |
.capture |
✅ | ✅ | 使用事件捕获模式 |
.self |
✅ | ✅ | 仅当事件目标为元素本身时触发 |
.once |
✅ | ✅ | 事件只触发一次 |
.passive |
✅ | ✅ | 提升滚动性能,不调用 preventDefault() |
.native |
✅ | ❌ | Vue 2 中监听组件根元素原生事件;Vue 3 中移除,默认即为原生 |
.left |
✅ | ✅ | 鼠标左键触发(鼠标事件) |
.right |
✅ | ✅ | 鼠标右键触发(鼠标事件) |
.middle |
✅ | ✅ | 鼠标中键触发(鼠标事件) |
.ctrl |
✅ | ✅ | Ctrl 键按下时触发 |
.alt |
✅ | ✅ | Alt 键按下时触发 |
.shift |
✅ | ✅ | Shift 键按下时触发 |
.meta |
✅ | ✅ | Meta 键(Win 键/Command 键)按下时触发 |
.exact |
✅ | ✅ | 精确控制系统修饰符组合(Vue 2.5.0+) |
示例对比
Vue 2
html
<template>
<!-- 基本修饰符 -->
<button @click.stop="handleClick">阻止冒泡</button>
<form @submit.prevent="onSubmit">阻止提交</form>
<!-- 组件原生事件 -->
<MyComponent @click.native="onNativeClick" />
<!-- 按键修饰符 -->
<input @keyup.enter="submit" />
<input @keyup.ctrl.enter="submit" />
<!-- 精确组合 -->
<button @click.ctrl.exact="onCtrlClick">仅 Ctrl 按下时触发</button>
</template>
Vue 3
html
<template>
<!-- 基本修饰符(相同) -->
<button @click.stop="handleClick">阻止冒泡</button>
<form @submit.prevent="onSubmit">阻止提交</form>
<!-- 组件原生事件(无需 .native) -->
<MyComponent @click="onNativeClick" />
<!-- 按键修饰符(相同) -->
<input @keyup.enter="submit" />
<input @keyup.ctrl.enter="submit" />
<!-- 精确组合(相同) -->
<button @click.ctrl.exact="onCtrlClick">仅 Ctrl 按下时触发</button>
</template>
主要变化总结
| 变化点 | 说明 |
|---|---|
移除 .native |
Vue 3 中组件事件默认为原生事件,需用 emits 选项声明自定义事件 |
| 其他修饰符 | 功能和使用方式完全一致,无变化 |
修饰符链式调用
两个版本都支持修饰符链式组合:
html
<!-- 阻止冒泡 + 阻止默认行为 + 只触发一次 -->
<a @click.stop.prevent.once="handleClick">链接</a>