1.Vue 组件间通信有哪几种方式?

(1)props / $emit 适用 父子组件通信

(2)ref 与 $parent / $children /.sync 适用 父子组件通信

  •  .sync 

父组件 <child :val.sync='foo'></child>
子组件 this.$emit('upate:val','数据')
子组件可以直接改变父组件的foo变量

(3)EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信

(4)$attrs/$listeners 适用于 隔代组件通信(2.4.0新增)

   inheritAttrs默认为false会继承(除了prop传递的属性、class 和 style )的所有属性 ,如果为true就不在继承;这个属性不熟悉可以查询官网。

下面例子将介绍,孙子组件如何拿到父组件的数据和如何触发父组件的的事件

父组件
  <div>
      <child :foo="foo" @test="test"></child>
  </div>
  data(){
     return{
        foo:'我是父组件数据'
     }
  }
  methods:{
      test(){
          console.log('我是父组件事件')
      }
  }
  
  
 子组件
   <div>
      <grandson v-bind="$attrs" v-on="$listeners"></grandson >
  </div>

 
 孙子组件
 
 watch:{
   "attrs"(val){
       console.log(val) //{foo:"我是父组件数据"} 
   },
   "$listeners"(){
      this.$emit('test') //我是父组件事件
   }
 }

提示:子组件也可以 this.$attrs拿到父组件foo数据,this.$emit('test')去触发父组件

(5)provide / inject 适用于 隔代组件通信(2.2.0新增)

主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。

provide 提供数据,inject注入数据,2者需配合一起使用

父组件 提供coo
export default {
      对象式
    provide:{
       coo:this.msg
    }
    或者函数式
     provide () {
            return {
              for: 'demo'
            }
          },
         data(){
        return{
           msg:"父组件"
      }
    }
}
后代组件注入coo
export default {
    inject:["coo"],
    mounted(){
       console.log(this.coo) //父组件
    }
}

提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的

(6)Vuex 适用于 父子、隔代、兄弟组件通信

  主要包含以下模块

State:定义数据结构,设置默认的初始化状态

Getter:计算属性

Mutaion:在严格模式下,是更改store中状态的唯一方法

Action:用于处理异步数据

Module:允许将单一的store拆分多个store且同时保存在单一的状态树中