Vue父子孙组件数据传递 - $attrs与$listeners的使用

Vue-$attrs与$listeners的使用

公司项目中有需要父组件传递数据到子孙组件,并不是只传到子组件,有可能有3、4层嵌套、甚至更多。用props无限传递明显工作量大很多,而且嵌套太多可能会弄错。此时想到用$attrs。同样的,子孙组件要触发父组件的事件也不能无限嵌套$emit来出发,此时就可以用到$listeners。

vm.$attrs

  • 类型 { [key: string]: string }
  • 只读
  • 详细
    包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
    简单点讲就是包含了所以父组件在子组件上设置的属性(除了prop传递的属性、class 和 style )。

父组件

Vue父子孙组件数据传递 - $attrs与$listeners的使用_第1张图片

子组件

Vue父子孙组件数据传递 - $attrs与$listeners的使用_第2张图片子组件需要v-bing="$attrs"将$attrs的数据传递到下一层组件中。
如果子组件需要用到可以直接引用,也可以用computed属性计算引用。

孙组件

Vue父子孙组件数据传递 - $attrs与$listeners的使用_第3张图片注意一点,一定要用计算属性来注册数据,如果单纯的在data里面orderInfo:this. a t t r s . o r d e r I n f o , 数 据 是 不 响 应 的 , 父 组 件 的 数 据 变 动 后 , 子 孙 组 件 不 会 变 动 。 如 果 h t m l 文 件 里 面 直 接 用 attrs.orderInfo,数据是不响应的,父组件的数据变动后,子孙组件不会变动。如果html文件里面直接用 attrs.orderInfohtmlattrs.orderInfo.XX(如上面子组件一样),还是响应的。
我认为是data是在组件注册的时候定义的,此时等于直接给它定义一个死数据,并不会给响应的数据。用computed属性每次$attrs.orderInfo改动都会计算一次。

vm.$listeners

  • 类型 { [key: string]: Function | Array }
  • 只读
  • 详细
    包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=“ l i s t e n e r s " 传 入 内 部 组 件 — — 在 创 建 更 高 层 次 的 组 件 时 非 常 有 用 。 简 单 点 讲 它 是 一 个 对 象 , 里 面 包 含 了 作 用 在 这 个 组 件 上 所 有 的 监 听 器 ( 监 听 事 件 ) , 可 以 通 过 v − o n = " listeners" 传入内部组件——在创建更高层次的组件时非常有用。 简单点讲它是一个对象,里面包含了作用在这个组件上所有的监听器(监听事件),可以通过 v-on=" listeners"von="listeners” 将事件监听指向这个组件内的子元素(包括内部的子组件)。

父组件

Vue父子孙组件数据传递 - $attrs与$listeners的使用_第4张图片
Vue父子孙组件数据传递 - $attrs与$listeners的使用_第5张图片父组件用法和$emit传值一样

子组件

Vue父子孙组件数据传递 - $attrs与$listeners的使用_第6张图片
子组件如果需要触发父组件事件和下面孙组件触发一样,我这里没有这个需求。用v-on将$listeners传递给下一级组件。

孙组件

Vue父子孙组件数据传递 - $attrs与$listeners的使用_第7张图片
在这里插入图片描述触发了父组件的事件,然后更新之前的orderInfo信息,再通过$attrs又更新子孙组件,实现数据时间联动。

关于 inheritAttrs

  • 默认值:true

  • 详细:
    默认情况下父作用域的不被认作 props 的 attribute 绑定 (attribute bindings) 将会“回退”且作为普通的 HTML attribute 应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrs 到 false,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例 property $attrs 可以让这些 attribute 生效,且可以通过 v-bind 显性的绑定到非根元素上。

  • 注意:这个选项不影响 class 和 style 绑定。

借用网上的图片,这个属性是true(默认),用到的$attrs属性就会绑定到根元素上。
Vue父子孙组件数据传递 - $attrs与$listeners的使用_第8张图片
只需要在这里加上 inheritAttrs: false ,就不会出现上图状况了。
Vue父子孙组件数据传递 - $attrs与$listeners的使用_第9张图片

你可能感兴趣的:(Vue)