Vue3中router-view用v-bind="$attrs"无法传递事件的疑问
问题解答
这是Vue Router 4配合Vue 3的预期设计,原因和Vue 3对组件属性、事件的处理逻辑变化直接相关:
Vue 3中
$attrs的逻辑调整
Vue 2里$attrs包含所有未被组件props接收的属性,以及自定义事件;但Vue 3将组件的自定义事件从$attrs中彻底分离——只有非事件类的普通属性会被包含在$attrs里,自定义事件现在属于组件emits选项声明的独立范畴,不再和普通属性混在一起。router-view的v-slot渲染逻辑
当使用<router-view v-slot="{ Component }">时,这里的Component是路由匹配到的目标组件实例。你尝试的v-bind="$attrs"只能传递普通属性,无法携带自定义事件,所以子组件触发的upload事件自然无法通过这种方式向上冒泡。手动转发事件的合理性
你使用的<router-view v-slot="{ Component }" @upload="$event => $emit('upload', $event)">写法是完全正确的——因为需要显式地将子组件的事件转发给父组件。如果有多个事件需要传递,也可以通过对象批量绑定简化写法:<router-view v-slot="{ Component }" v-on="{ upload: $event => $emit('upload', $event), delete: $event => $emit('delete', $event) }">
对比Vue 2的差异:Vue 2里$attrs包含事件,所以当时可以直接通过v-bind="$attrs"传递事件到路由组件,但Vue 3的这个设计是为了更清晰地区分组件的属性和事件逻辑,属于框架设计的优化方向。
内容的提问来源于stack exchange,提问作者TomFree
相关产品推荐
相关产品推荐

