Vue 使用$attrs和$listeners组件间传值

2,438 阅读1分钟

注意:父组件传过来的值是子组件是不能改变的(父组件的值)。子组件只能改变自组件当前对象的值,并且数据不是响应式的,当父组件改变的时候,回覆盖你刚才改变的值。

首先我们知道父组件给子组件传值:

// 子组件接收的时候是
<Child :a='1' b='2' />
/**
* 这个时候子组件将接收父组件传的值
*/

{
 ....
 props: [a, b]
 ....
}

如果props只接收a 不接收b 那子组件里面可以获取b的值能获取到吗?

答案是可以的。

attrs:当一个组件没有声明任何prop时,这里会包含所有父作用域的绑定(classstyle除外)官网是这么说的,大概意思是说 attrs:当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外) 官网是这么说的,大概意思是说attrs接收props接收的值 和 class style之外的任何值。

  • 到这里我们已经知道了,父组件传给子组件的属性可以被 attrsprops接收。那attrs 和 props 接收。那 attrs 和 props 有什么区别呢,为啥不直接用$attrs来接收?。。。。。待续
  • 还有一个问题需要我们知道的,就是attrs只能父子间传值,不可以隔代相传。也就是不能爷孙组件传值。如果需要爷孙组件间传值。我们需要使用指令 v-bind="attrs"可以将当前实例中attrs" 可以将当前实例中atttrs的属性传给它的子组件,它的子组件可以使用props或者$attrs来接收。这样就实现来爷孙组件传值。

这里已经实现爷孙组件间传值。那孙组件怎么给爷组件传值呢?

  1. 这里我们需要借助与$listeners
  2. 我们需要知道自定义事件
    • 一般我们知道自定义事件是我们在当前自己的methods对象中定义,然后传给它的子组件。子组件可以使用emitemit(emit的第二个参数传给自定义事件接收)来触发自定义事件。这个也是我们常用子组件给父组件传值的方法之一
  3. 接下来我们来看一下自定义事件子组件怎么接收的。 可以知道子组件是用listeners来接收父组件传来的自定义事件。这些事件我们需要使用 listeners来接收父组件传来的自定义事件。 这些事件我们需要使用emit来触发。
  4. 这些方法都是在子组件中调用的,以上这些方法完全可以实现父子组件间的交互。这些不是我们现在讨论的。那有没有什么方法可以将自定义方法传入孙组件呢。那样孙组件只需要调用传入的自定义事件就可以完成数据交互啦
  5. 有个问题需要我们知道,listeners可以接收当前父组件传来的自定义事件,而且可以将当前组件的自定义事件合并一起传给当前子组件。这样孙组件可以使用listeners可以接收当前父组件传来的自定义事件,而且可以将当前组件的自定义事件合并一起传给当前子组件。这样孙组件可以使用emit触发事件实现数据交互。

总结:vm.attrsvm. attrs和vm. listeners : 都是父传子接收,不能隔代相传。为了解决这个问题我们使用v-bind="$attrs" v-on="$listeners" 将事件和值传给孙组件。