v-on=“$listeners“ 这个写法已经废弃了,如进行代替
vue3中v-on="$listeners"发生了什么
在 Vue 3 的虚拟 DOM 中,事件监听器现在只是以 on 为前缀的 attribute,这样它就成为了 $attrs 对象的一部分,因此 $listeners 被移除了
。
<template>
<label>
<input type="text" v-bind="$attrs" />
</label>
</template>
<script>
export default {
inheritAttrs: false
}
</script>
如果这个组件接收一个 id attribute 和一个 v-on:close 监听器,那么 $attrs 对象现在将如下所示:
{
id: 'my-input',
onClose: () => console.log('close 事件被触发')
}
需要删除所有的 $listeners 用法(vue2切换vue3的时候)
如何进行改造
1. 直接使用 v-on 绑定具体的事件
在 Vue 3 中,可以直接在子组件上使用 v-on 绑定具体的事件,而不是使用 $listeners。这种方式更明确,也更符合 Vue 3 的设计哲学。
<!-- 父组件 -->
<template>
<ChildComponent
v-on:child-event="handleChildEvent"
v-on:another-event="handleAnotherEvent"
/>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleChildEvent() {
console.log('Child event triggered');
},
handleAnotherEvent() {
console.log('Another event triggered');
}
}
};
</script>
<!-- 子组件 -->
<template>
<div>
<button @click="$emit('child-event')">Trigger Child Event</button>
<button @click="$emit('another-event')">Trigger Another Event</button>
</div>
</template>
2. 使用 emits 选项声明事件
Vue 3 引入了 emits 选项,用于显式声明组件可以触发的事件
。这有助于类型检查和文档生成。
<!-- 父组件 -->
<template>
<ChildComponent
v-on:child-event="handleChildEvent"
v-on:another-event="handleAnotherEvent"
/>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
emits: ['child-event', 'another-event'],
methods: {
handleChildEvent() {
console.log('Child event triggered');
},
handleAnotherEvent() {
console.log('Another event triggered');
}
}
};
</script>
<!-- 子组件 -->
<script>
export default {
emits: ['child-event', 'another-event']
};
</script>
<template>
<div>
<button @click="$emit('child-event')">Trigger Child Event</button>
<button @click="$emit('another-event')">Trigger Another Event</button>
</div>
</template>
3、使用组合式 API (Composition API)
如果你使用的是 Vue 3 的组合式 API,可以通过 emits 和 defineEmits
来处理事件。
<!-- 父组件 -->
<template>
<ChildComponent
v-on:child-event="handleChildEvent"
v-on:another-event="handleAnotherEvent"
/>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue';
const handleChildEvent = () => {
console.log('Child event triggered');
};
const handleAnotherEvent = () => {
console.log('Another event triggered');
};
</script>
<!-- 子组件 -->
<script setup>
const emit = defineEmits(['child-event', 'another-event']);
</script>
<template>
<div>
<button @click="emit('child-event')">Trigger Child Event</button>
<button @click="emit('another-event')">Trigger Another Event</button>
</div>
</template>
4、直接使用 $attrs 绑定事件监听器
在 Vue 3 中,$listeners 已经被并入 $attrs,所以你可以直接使用 $attrs 来绑定事件监听器。
<!-- 父组件 -->
<template>
<ChildComponent
@child-event="handleChildEvent"
@another-event="handleAnotherEvent"
/>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleChildEvent() {
console.log('Child event triggered');
},
handleAnotherEvent() {
console.log('Another event triggered');
}
}
};
</script>
<!-- 子组件 -->
<template>
<div v-bind="$attrs">
<button @click="$emit('child-event')">Trigger Child Event</button>
<button @click="$emit('another-event')">Trigger Another Event</button>
</div>
</template>
<script>
export default {
inheritAttrs: false // 可选,如果不希望根元素自动接收 $attrs
};
</script>