剖析Vue组件$listeners和$attrs在透传时和新增事件和属性的合并规则
2024-01-06 19:55:49
背景
在某些相对复杂的项目中,我们抽取的公共组件可能存在深层嵌套的场景,例如: 我们会在App.vue里带上业务中提供的数据,一层层的传递进去,在传递的过程中一般有两种方案:
-
通过props具名接收,
-
通过v-bind="obj"(注意,不是v-bind="{obj}")传递对象。
本文将重点讨论第二种方式。
组件透传
组件透传基本概念
组件透传是指在父子组件之间传递事件和属性,它是一种非常常用的组件通信方式。在Vue中,我们可以通过listeners和attrs来实现组件透传。
listeners是一个对象,它包含了组件的所有事件监听器。attrs是一个对象,它包含了组件的所有属性,除了props之外。
透传场景
通常有以下3种场景需要组件透传:
-
新增事件:我们希望在子组件中新增一个事件,以便在父组件中可以监听和响应这个事件。
-
新增属性:我们希望在子组件中新增一个属性,以便在父组件中可以动态设置这个属性。
-
透传事件和属性:我们希望将父组件的事件和属性透传到子组件,以便在子组件中可以监听和使用这些事件和属性。
透传实现
新增事件
<template>
<child-component @new-event="handleNewEvent"></child-component>
</template>
<script>
export default {
methods: {
handleNewEvent(event) {
// 在这里处理新增事件
}
}
}
</script>
新增属性
<template>
<child-component :new-prop="newProp"></child-component>
</template>
<script>
export default {
data() {
return {
newProp: 'newPropValue'
}
}
}
</script>
透传事件和属性
<template>
<child-component v-bind="$attrs" v-on="$listeners"></child-component>
</template>
listeners和attrs的合并规则
在子组件中,我们可以通过listeners和attrs来获取父组件透传过来的事件和属性。
listeners是一个对象,它包含了组件的所有事件监听器。attrs是一个对象,它包含了组件的所有属性,除了props之外。
当父组件透传事件和属性到子组件时,子组件中的listeners和attrs会被自动更新。
如果子组件中存在与父组件透传过来的事件同名的事件监听器,则子组件中的事件监听器会被覆盖。
如果子组件中存在与父组件透传过来的属性同名的属性,则子组件中的属性会被覆盖。
注意事项
注意点一:透传事件的命名
在透传事件时,我们需要特别注意事件的命名。
在子组件中,如果我们使用@new-event来监听父组件透传过来的事件,那么在父组件中,我们需要使用v-on:new-event来触发这个事件。
注意点二:透传属性的类型
在透传属性时,我们需要特别注意属性的类型。
在子组件中,如果我们使用:new-prop="newProp"来接收父组件透传过来的属性,那么在父组件中,我们需要使用v-bind:new-prop="newProp"来设置这个属性。
总结
组件透传是Vue中一种非常常用的组件通信方式。通过listeners和attrs,我们可以轻松地在父子组件之间传递事件和属性。
在使用组件透传时,我们需要特别注意事件的命名和属性的类型。