背景:添加快捷菜单功能,用到了递归组件。在最后一层添加按钮,点击时触发emit,在父组件中监听自定义事件。但自定义事件未执行。
代码:
// 父组件
<el-menu>
<quick-menu-item v-for="routes in menuList" :key="routes.id"
:item="routes" @clickBtn="getItem" />
</el-menu>
const getItem = item => {
console.log('getItem', item)
}
// 子组件 QuickMenuItem.vue
<template>
<el-sub-menu v-if="props.item?.children?.length" :index="props.item.id">
<template #title> {{ props.item.name }}</template>
<quick-menu-item
v-for="child in props.item?.children"
:key="child.id"
:item="child"
/>
</el-sub-menu>
<el-menu-item v-else>
{{ props.item.name }}
<el-button link @click="clickBtn(props.item)">点击</el-button>
</el-menu-item>
</template>
const emit = defineEmits(['clickBtn'])
const clickBtn = item => {
emit('clickBtn', item)
}
首先,如上述代码,直接emit,getItem() 方法并未执行。
其次,借鉴了 vue2 递归组件中,加 v-on="$listeners",可实现功能。vue3 $listeners 被移除,合并到$attrs身上。做了如下尝试:
<quick-menu-item
v-for="child in props.item?.children"
:key="child.id"
:item="child"
v-bind="$attrs"
/>
然而很遗憾,同样未执行getItem() 方法。
最后,直到看到有个回答说直接写,直接写?
<quick-menu-item
v-for="child in props.item?.children"
:key="child.id"
:item="child"
@clickBtn="clickBtn"
/>
结果,getItem() 方法 成功执行。事情解决。
思考:如果有多个事件需要触发,有没有更好的方式?而非直接添加多个事件方式?
The end.