vue中的父子组件,兄弟组件的传值方式有多种,常见的有如下的几种:
1.使用vuex注册全局变量。$store.state的方式接收和commit的方法更新
2.使用的v-bind和v-on自定义事件和参数,在子组件用props和$emit进行转发和接收。或者用事件总线$bus。
3.通用的sessionStrorage和localStorage进行接收。
4.插槽和v-model的方法。
5.provide和inject
6.$attrs和$listeners的方法
现在有一个需求,当我们有三个组件,分别是第一层,第二层,第三层,假设第一层给予了一些参数到了第二层,但是第二层只需要特定的几个参数和方法,剩余的都是第三层的东西。此时我们通常的做法是第二层使用props全部接受,然后再继续使用v-bind的方式给到第三层。
再有我们假设第三层有了结果需要返回给第一层,那么此时的做法是第三层使用$emit,第二层使用v-on自定义函数接受,然后第二层也使用一次$emit转发到第一层,然后第一层再继续使用v-on的自定义方法进行接收。这两种方式实际操作起来是可以实现功能。但是有些过于繁琐。
结果图:
父组件:
子组件:
其中,gcname是父组件给予孙组件的名字。需要我们先告诉子组件,然后子组件再告诉孙组件说你爷爷给你取名字啦。同样的,当爷爷生日的时候,孙子要给个祝福也得让子组件进行转达,这样子也太繁琐,需要让子组件一直当个传声筒,这久而久之这子组件都得神经衰弱。
孙组件:
那么有没有方法可以简化这两种操作呢,让父组件和子组件直接进行通话!答案是有的,即是我们接下来要讲的$attrs和$listeners
$attrs
解释: 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class
和 style
除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class
和 style
除外),并且可以通过 v-bind="$attrs"
传入内部组件——在创建高级别的组件时非常有用。
$listeners
解释: 包含了父作用域中的 (不含 .native
修饰器的) v-on
事件监听器。它可以通过 v-on="$listeners"
传入内部组件——在创建更高层次的组件时非常有用。
可能单纯的靠文本有点难以理解。那么接下来就附上代码解释。我们可以更改子组件,和孙组件的代码方法为下面的写法,即可以实现父组件和孙组件的直接通信。
子组件:
孙组件:
代码量减少了,功能也是和层层传递的代码写法一样的功能。$attrs和$listeners的写法在实际开发中更多的是封装了第三方的组件,例如在child组件中封装了饿了么的组件,那么可以在child中使用$attrs和$listeners传递给饿了么组件,在父组件直接传递方法和参数给予饿了么组件,例如size,type,clearable,@change等。