通过$listeners、inheritAttrs、$attr实现组件之间的数据通信

适用于一下场景中的组件通行

  • 项目比较小,不适合用VueX对状态进行处理
  • 组件嵌套比较深,使用props会很繁琐

缺点

  • 代码的可读性比较低
  • 代码维护性比较低

基本概念

inheritAttrs

默认情况下,子组件无法获取到
props中未定义的值。通过将
inheritAttrs=true禁止这种默认行为,配合
$attr获取到父作用域中所有的属性(除了props传递的属性以及Class或者Style)来进行父组件向子组件传值

vm.$attr

只读的VUE实例属性,包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外),并且可以通过
v-binnd=$arrts传入内部组件中

vm.$listeners

包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件——在创建更高层次的组件时非常有用。

DEMO

App.vue
   <template>
      <child1 :words1="text1" :words2="text2" :words3="text3" v-on:event1="goEvent1" v-on:event2="goEvent2">
      </child1>
   </template>
   <script>
      import Child1 from '@components/child1.vue'
       export default {
           name: 'app',
           data () {
               return {
                   text1: 1,
                   text2: 2,
                   text3: 3
               }
           },
           methods: {
               goEvent1() {
                    console.log('child 提交成功');
                },
                goEvent2(value) {
                    console.log(value);
                }
           }
       }
   </script>
   
child1.vie
   <template>
       <div class="child-1">
          <p>props: {{words1}}</p>
          <p>$attrs: {{$attrs}}</p>
          <button @click="submit()">提交</button>
          <hr>
          <child2 v-bind="$attrs" v-on="$listeners"></child2>
          <!-- 通过$listeners将父作用域中的v-on事件监听器,传入child2,使得child2可以获取到app中的事件 -->
       </div>
    </template>
    <script>
    import Child2 from './child2.vue'
    export default {
        name: 'child1',
        props: ['words1'],
        data() {
          return {};
        },
        inheritAttrs: false,
        components: { Child2 },
        methods: {
          submit () {
            this.$emit('event1', 'child1 提交事件')
          }
        }
    }
    </script>
    
child2.vue
    <template>
      <div>
        <div class="child-2">
          <p>props: {{words2}}</p>
          <p>$attrs: {{$attrs}}</p>
          <input v-model="inputValue" name="" id="" @input="goInput">
        </div>
      </div>
    </template>
    <script>
    export default {
        name: 'child2',
        props: ['words2'],
        data() {
            return {
              inputValue: ''
            };
        },
        inheritAttrs: false,
        mounted() {
        },
        methods: {
          goInput () {
            this.$emit('event2', this.inputValue);
          }
        }
    }
    </script>

以上是通过学习,我对这种通信方式的总结,对于我来说,可能不常用,不过也加深了我对组件的理解,大家多多交流吧~

    原文作者:JOUEN
    原文地址: https://segmentfault.com/a/1190000019629439
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞