issues问题🔗如下:
复现流程:
Parent:
<template>
<div>
<Mid @myEvent="myEventHandler" />
</div>
</template>
<script>
import Mid from "./Mid.vue";
export default {
components: { Mid },
methods: {
myEventHandler() {
console.log("triggered");
},
},
};
</script>
Mid组件:
<template>
<div>
<Child v-bind="$attrs" />
</div>
</template>
<script>
import Child from "./Child.vue";
export default {
emits: ["myEvent"],
inheritAttrs: false,
components: { Child },
mounted(){
console.log("Mid: ",this.$attrs)
}
};
</script>
Child组件:
<template>
<button @click="$emit('myEvent')">Emit Child</button>
</template>
<script>
export default {
mounted() {
console.log("Child: ", this.$attrs);
},
};
</script>
操作点击Child组件的Emit Child按钮,并没有触发Parent的myEventHandler事件
PS: 其实这个issues并不是真正的bug,却引发了讨论
首先咱们就来看看为什么,首先从Parent入手:
1.Parent要做的只有一件事,引入Mid组件,并将自身的myEventHandler方法传给Mid,传值方式为:@myEvent
2.Mid组件用emits接收了myEvent事件,并在mounted挂载阶段输出了this.$attrs
3.Child组件mounted挂载阶段输出了this.$attrs,并且在按钮的点击事件中调用了emit定义的myEvent
最后的结果为:
Child: Proxy {__vInternal: 1}
Mid: Proxy {__vInternal: 1}
并没有从$attrs中获取到myEvent,最后的myEvent也没有调用成功
emit传递数据到Mid组件后并没有继续传递到Child,而是把attrs传到Child组件上,而从刚才输出的MId可以发现,并没有输出emit传递的myEvent,可以得知,attrs并不会传递给定义给组件的emit选项,我们试着将Mid修改一下,去掉emits: ["myEvent"],可得到如下输出:
Child: Proxy {__vInternal: 1, onMyEvent: ƒ}
Mid: Proxy {__vInternal: 1, onMyEvent: ƒ}
由此得知,$attrs并不会传递emits选项中的事件,这引发了一个关于vue-next框架的讨论,有兴趣可以看看