生活需要时时的小惊喜,代码需要常常的新想法。给波澜不惊的生活,增加了一丝绚丽多彩的意义。
需求描述:在功能设计开发过程中,message 组件 是 list 组件的父组件,list 组件是 item 组件的父组件。我们从 message 组件中传递一个属性到 list 组件,再由 list 组件中传递给 item 组件。对于这种组件嵌套多层的数据传递如何避免一层一层地传递呢?
在父子组件间进行数据通信,父组件通过 props 传递数据给子组件,子组件通过 emit 发送事件传递数据给父组件,这两种方式是最常用的父子通信实现的方式。子组件不能直接修改 props ,而是通过发送事件的方式告知父组件修改数据。
在多级组件嵌套需要传递数据时,通常使用 Vuex 做全局数据状态管理。如果只是传递数据,而不做中间处理,使用 Vuex 处理就显得有些多余了。Vue 2.4 中提供了 v-bind="$attrs" 方法,将父组件中不作为 props 被识别的 attribute 绑定的属性传入子组件中。
$attrs 和 $listeners 就是为了解决多级组件嵌套通过 props 和 $emit 的方式一层一层的传递数据,中间组件只是作为传递数据中转站的问题。
// message 组件
<list
:list-data="msgTable.informs"
:readed-list="readedList"
@click="itemClick"
/>
itemClick (item) {
console.log('listeners', item)
},
// list 组件
<item
v-for="item of listData"
:key="item.id"
:item-data="item"
v-bind="$attrs"
v-on="$listeners"
/>
// item 组件
props: {
readedList: {
type: Array,
required: true,
},
},
itemClick (item) {
this.$emit('click', item)
},
知识点总结:
1.$attrs:包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class
和 style
除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class
和 style
除外),并且可以通过 v-bind="$attrs"
传入内部组件——在创建高级别的组件时非常有用。
2.$listeners:包含了父作用域中的 (不含 .native
修饰器的) v-on
事件监听器。它可以通过 v-on="$listeners"
传入内部组件——在创建更高层次的组件时非常有用。