如果存在组件之间层级大于2层,中间需要一个过渡层的时候,属性和事件的上传下达越简洁越好,重点就是采用vue里的$atts 和事件 $listeners,先打印看看这两者是什么玩意,
| 12
 
 | $attrs: object,$listeners: object
 
 | 
两者都是绑定在组件里的,且是对象类型,所以在组件阔以之间用this.$attrs.info去获取祖父组件传来的info信息。
以下有三个组件,三者之间都是相关有联系的,阔以称之为 祖父组件、父组件以及子组件。
伪代码如下
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | // grandParent.vue<template>
 <div class="home">
 <Parent
 :childMsg='childMsg'
 @triggerClickChild='triggerClickChild'
 info='父组件'
 />
 </div>
 
 </template>
 
 <script lang="ts">
 import { Component, Vue } from 'vue-property-decorator';
 import Parent from '../components/parent.vue'; // @ is an alias to /src
 
 @Component({
 components: {
 Parent,
 },
 })
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | // parent.vue<Child
 label='子组件信息'
 class='child'
 v-bind='$attrs'
 v-on='$listeners'
 @triggerClickChild='parentC'
 />
 
 import Child from './child.vue'
 @Component({
 components: {
 Child
 }
 })
 export default class Parent extends Vue {
 @Prop() private childMsg!: any; // 此时childMsg信息已用所以不会传递到子组件
 private parentC(key: string) {
 console.log(key, '中间层截胡')
 }
 private mounted() {
 console.log(this.childMsg, 'props')
 console.log(this, '中间组件')
 }
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | // child本身的组件<div class="hello">
 <h1 @click='triggerClickChild'>{{$attrs}}</h1>
 </div>
 
 @Component({
 inheritAttrs: false
 })
 export default class HelloWorld extends Vue {
 private triggerClickChild() {
 this.$emit('triggerClickChild', 'triggerClickChild子孙组件');
 }
 private mounted() {
 console.log(this, 'attrs') // {info: '',label: '',  }
 console.log(this.$listeners) // fn triggerClickChild
 }
 }
 
 | 
梳理以上几个组件发现这几点:
1.v-bind=’$atts’ 和 v-on=’$listeners’只能用于中间组件的传递,也就是起到承上启下的作用
2.中间组件接受的props,一旦被采用,也就无法传递到下一层。but事件,中间层阔以截胡,因为事件是由下往上,父组件和祖父组件都能接收到
3.有个弊端,如果中间层需要对数据进行二次加工,$attrs也就无用武之地,所以最好就是在顶层组件进行处理,如果处理不了就只能Props一层层传
4.当然最大的优势还是免除一层层传递,事件和属性这样简写一下高效了许多。