vue组件之间传值的方式(inheritAttrs + $attrs + $listeners)

组件之间传递数据的方式可能有

  • 父组件通过 props 的方式向子组件传值
  • 子组件通过 $emit 传递的方法参数向父组件传值
  • 使用 vuex 进行状态管理
  • 兄弟组件之间可以使用 event bus 事件总线传值
  • 非父子组件之间使用 inheritAttrs + $attrs + $listeners 传值(跨多级的组件嵌套关系)
    这里主要讲最后一种方式传值
    应用场景图大概是这样
    vue组件之间传值的方式(inheritAttrs + $attrs + $listeners)_第1张图片
    三个组件,A组件与B组件是父子组件,A组件与C组件是跨多级的组件嵌套关系
    代码示例:
    fatherA.vue
<template>
  <div>
    <!-- 此处,v-on 监听了两个事件,可以在子组件和子子组件中直接触发 -->
    <child-b :childB="childB" :grandson="grandson" @test1="onTest1" @test2="onTest2"></child-b>
  </div>
</template>

<script>
import childB from './childB'
export default {
     
  name: 'fatherA',
  components: {
     
    childB
  },
  data() {
     
    return {
     
      childB: 'myChildB',
      grandson: 'myGrandSon'
    }
  },
  methods: {
     
    onTest1() {
     
      console.log('test1 running...')
    },
    onTest2() {
     
      console.log('test2 running...')
    }
  }
}
</script>

childB.vue

<template>
  <div class="child-b">
    <p>in childB</p>
    <p>props: {
     {
     childB}}</p>
    <p>$attrs: {
     {
     $attrs}}</p>
    <!-- grandsonC 组件中能直接触发 test2 方法的原因在于, childB 组件在调用 grandsonC 组件时,使用
    v-on 绑定了 $listeners 属性 -->
    <!-- 通过 v-bind 绑定 $attrs 属性,grandsonC 组件可以直接获取到 fatherA 组件中传递
    下来的 props (除了 childB 组件中 props 声明的)-->
    <grandson-c v-bind="$attrs" v-on="$listeners"></grandson-c>
  </div>
</template>

<script>
import grandsonC from './grandsonC'
export default {
     
  props: ['childB'],
  inheritAttrs: false,
  components: {
     
    grandsonC
  },
  mounted() {
     
    this.$emit('test1')
  }
}
</script>

grandsonC.vue

<template>
  <div class="grand-son">
    <p>in grandSonC</p>
    <p>props: {
     {
     grandson}}</p>
    <p>$sttrs: {
     {
     $attrs}}</p>
  </div>
</template>

<script>
export default {
     
  props: ['grandson'],
  inheritAttrs: false,
  mounted() {
     
    this.$emit('test2')
  }
}
</script>

最后的结果
vue组件之间传值的方式(inheritAttrs + $attrs + $listeners)_第2张图片
根据结果分析:
B组件中的 $attrs 是父组件A中不被认为是 props 的值,并且B组件通过 v-bind="$attrs"传入了内部组件C组件中
B组件中通过 v-on="$listeners"将父组件中的方法传入了内部组件C组件中

$attrs

  • 类型:{ [key: string]: string }
  • 只读
  • 详细:包含了父作用域中不作为 prop 被识别(且获取)的 attribute 绑定(classstyle 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定(classstyle 除外),并且可以通过 v-bind="$attrs“” 传入内部组件–在创建高级别的组件时非常有用

$listeners

  • 类型:{ [key: string]: Function | Array }
  • 只读
  • 详细:包含了父作用域中的(不含 .native修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件-- 在创建更高层次的组件时非常有用

inheritAttrs

  • 类型 : Boolean
  • 默认值: true
  • 注意:这个选项不影响 classstyle 的绑定
  • 详细:默认情况下,父作用域的不被认作 props 的 attribute 绑定(attribute bindings) 将会 “回退” 且作为普通的 HTML attribute 应用在子组件的根原生上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrsfalse ,这些默认行为将会被去掉。而通过实例 property $attrs 可以让这些 attribute 生效,且可以通过 v-bind 显性的绑定到非根元素上。
    这里用上面的代码简单做一个比较示例看一下 inheritAttrs 分别设置为 truefalse 的区别。我们就使用上面的组件A,B,C的代码做一下示例
    先是 inheritAttrs: false
    vue组件之间传值的方式(inheritAttrs + $attrs + $listeners)_第3张图片
    vue组件之间传值的方式(inheritAttrs + $attrs + $listeners)_第4张图片
    组件B和组件C都设置为 false,我们来看源代码的效果
    vue组件之间传值的方式(inheritAttrs + $attrs + $listeners)_第5张图片
    接下来我们把 B组件设置为 inheritAttrs: true
    vue组件之间传值的方式(inheritAttrs + $attrs + $listeners)_第6张图片
    看一下源代码效果
    vue组件之间传值的方式(inheritAttrs + $attrs + $listeners)_第7张图片
    这个时候就验证了 inheritAttrs 的详细说明中的内容

你可能感兴趣的:(vue,vue)