vue组件间的通信方式

组件化的目的:复用性强,可维护性高,提升开发效率,方便单元测试

一,props

这是vue父组件向子组件传参最常用的方式

//parent
<template> <div> <child name="child"></child> </div> </template> <script> import child from './child.vue' export default { name: 'parent', data () { return { } }, components:{ child } } </script>
//child
<template>
  <div>
    我是{{name}}子组件
  </div>
</template>

<script>
export default {
  props:{
    name: {
      type: String,
      default: 'child'
    },

  }

}
</script>

二,emit

子组件通过$emit发布事件,子组件在父组件中通过v-on订阅事件

//child
<template>
  <div>
    <button @click="sentMsg">点击向父组件传参</button>
  </div>
</template>

<script>
export default {
  methods:{
    sentMsg(){
      this.$emit('onMsg','子组件传来的信息')
    }
  }
}
// parent
<template>
  <div>
    <child name="child" @onMsg="onMsg"></child>
  </div>
</template>
<script>
import child from './child.vue'
export default {
  name: 'parent',
  data () {
    return {
    }
  },
  components:{
    child
  },
  methods:{
    onMsg(val){
      console.log(val)
    }
  }
}

三,Event Bus

通过创建一个vue的实例作为中央事件总线,用它来发布和订阅事件,实现父子,兄弟,跨级等组件间的通信。

第一步:创建一个新的bus.js文件,创建一个新的vue实例

import Vue from 'Vue'
export default new Vue

第二步:通过$emit发布事件,传递参数

bus.$emit('eventbus','通过eventbus实现子组件传来的信息')

第三步:通过$on订阅事件,接受参数

bus.$on('eventbus',val=>{
    console.log(val)
})

第四步:清除事件总线

beforeDestroy(){
    bus.$off('eventbus')
  }

eventBus实现原理:

class bus{
      constructor(){
        this.callbacks = {}
      }
      $on(name,fn){
        this.callbacks[name] = this.callbacks[name] || []
        this.callbacks[name].push(fn)
      }
      $emit(name,args){
        if(this.callbacks[name]){
          this.callbacks[name].forEach(item => {
            item(args)
          });
        }
      }
      $off(name,fn){
        if(this.callbacks[name].indexOf(fn) != -1){
          this.callbacks[name].splice(this.callbacks[name].indexOf(fn), 1)
        }
      }
    }

四,vuex

vuex是vue的状态管理器,Vuex 实现了一个单向数据流,在全局拥有一个 State 存放数据,当组件要更改 State 中的数据时,必须通过 Mutation 进行,Mutation 同时提供了订阅者模式供外部插件调用获取 State 数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走 Action,但 Action 也是无法直接修改 State 的,还是需要通过 Mutation 来修改 State 的数据。最后,根据 State 的变化,渲染到视图上。

 

vue components: vue组件,通过$store.dispatch('action名',data)触发actions中的某一个action通过commit('mutation名',data)触发moutations实现state改变;

getters:state 对象读取方法。图中没有单独列出该模块,应该被包含在了 render 中,Vue Components 通过该方法读取全局 state 对象。

五,$attrs 和 ¥listeners

多级组件嵌套需要传递数据时,通常使用的方法是通过 vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此 Vue2.4 版本提供了另一种方法----$attrs/$listeners

  • $attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用。
  • $listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件

六,provide/inject

Vue2.2.0 新增 API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。一言而蔽之:祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。
provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

七,$parent/$children/$refs/$root

posted @ 2021-02-23 10:13  乘风破浪的哥哥  阅读(70)  评论(0)    收藏  举报