返回

剖析Vue组件$listeners和$attrs在透传时和新增事件和属性的合并规则

前端

背景

在某些相对复杂的项目中,我们抽取的公共组件可能存在深层嵌套的场景,例如: 我们会在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,我们可以轻松地在父子组件之间传递事件和属性。

在使用组件透传时,我们需要特别注意事件的命名和属性的类型。