一、.native修饰符
在vue2中,写在组件标签上的事件默认是自定义事件。例如:
javascript
<MyButton @click="handleClick" />
这里,写在MyButton组件上的click事件不会被触发,因为@click监听的是组件内的通过$emit触发的自定义事件,而不是原生的click事件
而.native修饰符的作用则是将事件监听器直接绑定到组件的根元素 上,用于监听组件上的原生DOM事件(如click、input等)。例如:
javascript
// 父组件
<MyButton @click.native="handleClick" />
//子组件
<template>
<button>Click Me</button>
</template>
这里,vue根据@click.native,会将事件监听器直接绑定到组件的根元素上,也就是说click事件会绑定到<button>上;且如果<button>上已经绑定了的click事件监听器会被覆盖
注意,.native修饰符只能监听组件根元素的原生事件,如果组件的根元素不是目标元素,事件不会被触发。例如:
javascript
<template>
<div>
<button>Click Me</button>
</div>
</template>
在这种情况下,@click.native会将事件绑定到<div>上,而不是<button>上
注意:Vue3中,.native修饰符被移除,如需监听原生事件,可直接使用v-on或emits选项显式声明事件
二、$listeners组件属性
在Vue2中,$listeners是一个特殊的组件属性,用于获取父组件通过v-on绑定在当前组件上的所有事件监听器;子组件中可以使用v-on="$listeners"将父组件的事件监听器绑定到的特定元素上。例如:
javascript
// 父组件 @click = v-on:click
<MyButton @click="handleClick" />
// 子组件
<template>
<div>
<button v-on="$listeners">Click Me</button>
</div>
</template>
这里的$listeners会将父组件的事件监听器绑定到<button>上,会覆盖掉<button>元素上原有的事件监听器
$listeners的结构
$listeners是一个对象,键是事件名,值是对应的回调函数。例如:
javascript
{
click: function() { ... },
input: function() { ... },
customEvent: function() { ... }
}
$listeners的高级用法
-
结合
v-on和$listeners
可以将$listeners与其他事件监听器结合使用javascript<template> <button v-on="{ ...$listeners, mouseover: handleMouseOver }">Click Me</button> </template> <script> export default { methods: { handleMouseOver() { console.log('Mouse over!'); }, }, }; </script> -
过滤或修改事件监听器
可以通过计算属性对$listeners进行过滤或修改javascript<template> <button v-on="filteredListeners">Click Me</button> </template> <script> export default { computed: { filteredListeners() { //过滤掉某些事件 const listeners = { ...this.$listeners }; delete listeners.customEvent; return listeners; } } } </script>
注意:Vue3中,$listeners被移除。事件监听器会被包含在$attrs中,可以通过v-bind="$attrs"传递
三、.native和$listeners同时使用
javascript
// 父组件
<MyButton @click.native="handleNativeClick" @click="handleCustomClick" @touchstart="handleTouchStart"/>
// 子组件
<template>
<div>
<button v-on="$listeners">Click Me</button>
</div>
</template>
这里,@click.native会将handleNativeClick事件绑定到<MyButton>的根元素,即<div>上;而v-on="$listeners"会将父组件的事件监听器(包括@click="handleCustomClick"和@touchstart="handleTouchStart")绑定到<button>上
ps: 为什么handleNativeClick事件不受$listeners影响呢?
$listeners只包含父组件通过v-on绑定的非 .native 的事件监听器;换句话说,$listeners只会收集通过$emit触发的自定义事件