组件通信之 $attrs 和 $listeners
# $attrs
# 介绍
官方解释:
包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class
和 style
除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class
和 style
除外),并且可以通过 v-bind="$attrs"
传入内部组件——在创建高级别的组件时非常有用。
简单来说:
包含了所有父组件在子组件上设置的属性(除了prop
传递的属性、class
和 style
)。
# 图解
例一:
下图中,在parent.vue
中给子组件child.vue
设置了name
、age
、gender
三个属性。因为子组件child.vue
通过props
声明了name
属性,所以this.$attrs
最后输出{ age: "20", gender: "man" }
。
例二:
另外可以在grandson.vue
上通过 v-bind="$attrs"
, 将属性继续向下传递,让 grandson.vue
也能访问到父组件的属性,这在传递多个属性时会显得很便捷,而不用一条条的进行绑定。
如果想要添加其他属性,可继续绑定属性。但要注意的是,继续绑定的属性和$attrs
中的属性有重复时,继续绑定的属性优先级会更高。
# $listeners
# 介绍
官方解释:
包含了父作用域中的 (不含 .native
修饰器的) v-on
事件监听器。它可以通过 v-on="$listeners"
传入内部组件——在创建更高层次的组件时非常有用。
我的理解:
接收除了带有.native事件修饰符的所有事件监听器
# 图解
例一:
parent.vue
中对child.vue
绑定了两个事件,带有.native
的click
事件和一个自定义事件,所以在 child.vue
中,输出$listeners
的结果为:
{ customEvent: fn }
例二:
同 $attrs
属性一样,可以通过v-on="$listeners"
,将事件监听器继续向下传递,让grandson.vue
访问到事件,且可以使用$emit
触发 parent.vue
的函数。
如果想要添加其他事件监听器,可继续绑定事件。但要注意的是,继续绑定的事件和 $listeners
中的事件有重复时,不会被覆盖。当 grandson.vue
触发 customEvent
时,child.vue
和 parent.vue
的事件都会被触发,触发顺序类似于冒泡,先到 child.vue
再到 parent.vue
。