引言

        多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。如果为了传递数据而无中间层处理,则可以使用Vue中提供的$attrs和$listeners

 

父子AB组件通讯

        A to B 通过props的方式向子组件传递,B to A 通过在 B 组件中 $emit, A 组件中 v-on 的方式实现

/** 组件A */
<template>
    <compoentB
      @data-add="handleAdd"
    ></compoentB>
    ....
<template>
<script>
    export default {
        methods: {
            handleAdd(data) {}
        }
        ...
    }
</script>


/** 组件B */
<template>
    <compoentC></compoentC>
    ....
<template>
<script>
    export default {
        methods: {
            emitComponentA() {this.$emit('data-add',{key:123})}
        }
        ...
    }
</script>

祖孙AC组件嵌套通讯

        借助 B 组件的中转,从上到下props依次传递,从下至上,$emit事件的传递,达到跨级组件通信的效果。这种通过props和$emit的方式,使得组件之间的业务逻辑臃肿不堪,B组件在其中仅仅充当的是一个中转站的作用。

        $attrs以及$listeners的出现使得B组件在其中传递props以及事件的过程中,不必在写多余的代码,仅仅是将$attrs以及$listeners向上或者向下传递即可。

 引入概念:

$attrs

接收除了props声明外的所有绑定属性(class、style除外)

 $listeners

接收除了带有.native事件修饰符的所有事件监听器

inheritAttrs

如果你不希望组件的根元素继承特性,你可以在组件的选项中设置 inheritAttrs: false。

这个解释可能过于抽象,那么我们来看看例子。

 

/*父组件*/
<template>
   <div class="parent">
    <child-component aaa="1111"></child-component>
  </div>
</template>

/*子组件*/
<template>
  <div class="child">子组件</div>
</template>
<script>
    export default {
        inheritAttrs: true,
    }
</script>

 如果在子组件里把inheritAttrs设置为false

由上述例子可以看出,前提:子组件的props中未注册父组件传递过来的属性。

1.当设置inheritAttrs: true(默认)时,子组件的顶层标签元素中(本例子的div元素)会渲染出父组件传递过来的属性(本例子的aaa="1111")。

2.当设置inheritAttrs: false时,子组件的顶层标签元素中(本例子的div元素)不会渲染出父组件传递过来的属性(本例子的aaa="1111")。

3.不管inheritAttrs为true或者false,子组件中都能通过$attrs属性获取到父组件中传递过来的属性。

/** 组件A */
<template>
 <componentB
  :prop1="Hi"
  :prop2="Hello"
  @do1="onDo1" //此处监听了两个事件,可以在B组件或者C组件中直接触发
  @do2="onDo2"
 </componentB>
</template>

/** 组件B */
<script>
 // 接受了prop1属性
 props: ['prop1'],
 inheritAttrs: false
</script>
<template>
 // 显示hi
 <P>{{prop1}}</P>
 // 组件B没有接受prop2,所以$attrs中剩余prop2 显示{'prop2':'Hello'}
 <P>{{$attrs}}</P>
 <componentC
  v-bind="$attrs" v-on="$listeners"
 </componentC>
</template>

/** 组件C */
<script>
 // 接受了prop2属性,此时$attr为空,如果不接受prop2,则$attr包含着prop2
 props: ['prop2'],
 inheritAttrs: false
</script>
<template>
 // 显示Hello
 <P>{{prop1}}</P>
 // {}
 <P>{{$attrs}}</P>
</template>

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐