父子组件间通信

父向子传递信息,通过v-bind 绑定到子组件标签上,子组件通过props进行接收。
子向父传递数据通过$emit('事件名','参数') 的方法 在父组件上 通过对子组件标签的v-on绑定事件名,自定义方法中接收。

非父子组件间通信

1.bus总线

$bus有点类似于$emit。
   var Event=new Vue();
    Event.$emit(事件名,数据);
    Event.$on(事件名,data => {});

2.$attrs

普通的父子组件通信,采用子组件上v-bind绑定父组件需要传递的参数,子组件内部使用props进行接收

//父组件 (c1为子组件 c11为子组件的子组件)
<template>
  <div>
    <c1 :message1="message1" :message2="message2"></c1>
  </div>
</template>

 data(){
    return {
      message1: 'hello',
      message2: 'hi'
    }
  },

可以看出我们父组件有message1和message2两个参数传递给了子组件c1。但是在子组件C1中代码

<template>
<div>
  <p>{{message1}}</p>
  <p>{{$attrs}}</p>
</div>
</template>

<script>
import C11 from './C11.vue'
export default {
  name: 'C1',
  props: ['message1'],
  components: {
    C11
  }
}
</script>

C1的props中只接收一个message1,没有接收message2 控制台中显示为

<c1 message2="hi">
    <p>hello</p>
</c1>

可以看出没有被使用的参数停留在根标签中。现在我们可以使用$attrs来进行对message2的打印打印出来的是所有未被props定义的参数所组成的对象

hello
{"message2" : "hi"}
//此时的控制台
<div message2="hi">
    <p>hello</p>
    <p>{"message2" : "hi","key":"value"}</p>
</div>

可以看到根标签中依旧存在message2="hi",我们可以使用 inheritAttrs:false,来禁止这个默认事件,虽然禁止了默认事件,但是通过实例属性$attrs ,可以将这些特性生效,且可以通过v-bind 绑定到子组件的非根元素上。

//组件C
<template>
<div>
  <p>{{message1}}</p>
  <p>{{$attrs}}</p>
  <c11 v-bind="$attrs"></c11> //通过v-bind将$attrs绑定到子组件C11
</div>
</template>

//C11
<template>
  <div>
    <p>{{message2}}</p>
  </div>
</template>
  props: ['message2'], //使用proprs进行对message2的接收

如果不进行接收可以通过绑定$attrs一直向下传递,直到有一个组件用props接收。


3.$listeners

对于父子组件间,子组件可以直接$emit将参数发送给父组件。但是在有孙子组件的时候,如果还想把孙子组件的参数发送给爷组件就要使用$listeners.

<template>
  <div class="root1">
    我是组件1
    <!--
       @changeData ***是在组建3中定义的
       @sendData ***是在组件2中定义的
       -->
    <component2 @changeData="changeData" @sendData="sendData" />
    <div>组件2传递给我的数据为:{{ msg2 }}</div>
    <div>组件3传递给我的数据为:{{ msg3 }}</div>
  </div>
</template>

//子组件

<template>
  <div class="root2">
    我是组件2
    <el-button @click="send()">传递数据给组件1</el-button>
    <component3 v-on="$listeners"/>
  </div>
</template>
  methods: {
    send(){
      this.$emit('sendData','数据2');
    }
}

//孙子组件

<template>
  <div class="root3">
    我是组件3
    <el-button @click="transmit()">传递数据给组件1</el-button>
  </div>
</template>
 methods: {
    transmit(){
      this.$emit('changeData','数据3');
    }
  }
使用$listeners就能监听到孙子组件的$emit事件

4.vuex

vuex提供全局状态管理,vuex中的数据全局都可以共享。

5.parent、children、ref

其中常用到的是ref  
<div>
    <child ref="child"></child>
</div>

父组件通过this.$refs.child就可以访问子组件,包括子组件的数据和方法。

$chidren
他返回的是一个组件集合,如果你能清楚的知道子组件的顺序,你也可以使用下标来操作;
for(let i=0;i<this.$children.length;i++){
    console.log(this.$children[i].message);输出子组件的message数据;
 }

$parent
子组件可以通过this.$parent来获取父子组件的数据或者进行修改
getParentMsg(){
   this.$parent.parentMsg="子组件中可以修改父组件的内容"
   this.msg=this.$parent.parentMsg;
}