四十五、通信方式总结


通信方式整体来讲能够分为两大类:

  1. 父子组件通信
  2. 跨层级组件通信

父子组件通信

  1. Props:通过 Props 可以实现父组件向子组件传递数据。
  2. Event:又被称之为自定义事件,原理是父组件通过 Props 向子组件传递一个自定义事件,子组件通过 emit 来触发自定义事件,触发自定义事件的时候就会传递一些数据给父组件
  3. 属性透传:一些没有被组件声明为 props、emits 或自定义事件的属性,但依然能传递给子组件,例如常见的 class、style 和 id.
  4. ref引用:ref除了创建响应式数据以外,还可以拿来作为引用。
  5. 作用域插槽:子组件在设置 slot 的时候,上面绑定一些属性,回头父组件通过 v-slot 来拿到这些属性。

跨层级组件通信

  1. 依赖注入:通过 provide(提供数据方)和 inject(注入数据方)来实现的。
  2. 事件总线:从 Vue2 时期就支持的一种通信方式。从 Vue3 开始更加推荐 依赖注入 或者 Pinia 来进行组件通信。不过事件总线这种方式仍然保留了下来。
    • 原理:本质上是设计模式里面的观察者模式,有一个对象(事件总线)维护一组依赖于它的对象(事件监听器),当自身状态发生变化的时候会通过所有的事件监听器。
    • 核心操作:
      1. 发布事件:发布通知,通知所有的依赖自己去执行监听器方法
      2. 订阅事件:其他对象可以订阅某个事件,当事件发生时,就会触发相应的回调函数
      3. 取消订阅
    • 事件总线的核心代码如下:
class EventBus {
  constructor() {
    // 维护一个事件列表
    this.events = {}
  }

  /**
   * 订阅事件
   * @param {*} event 你要订阅哪个事件
   * @param {*} listener 对应的回调函数
   */
  on(event, listener) {
    if (!this.events[event]) {
      // 说明当前没有这个类型
      this.events[event] = []
    }
    this.events[event].push(listener)
  }

  /**
   * 发布事件
   * @param {*} event 什么类型
   * @param {*} data 传递给回调函数的数据
   */
  emit(event, data) {
    if (this.events[event]) {
      // 首先有这个类型
      // 通知这个类型下面的所有的订阅者(listener)执行一遍
      this.events[event].forEach((listener) => {
        listener(data)
      })
    }
  }

  /**
   * 取消订阅
   * @param {*} event 对应的事件类型
   * @param {*} listener 要取消的回调函数
   */
  off(event, listener) {
    if (this.events[event]) {
      // 说明有这个类型
      this.events[event] = this.events[event].filter((item) => {
        return item !== listener
      })
    }
  }
}

const eventBus = new EventBus()
export default eventBus
  • 除了像上面一样自己来实现事件总线以外,还可以使用现成的第三方库 mitt.
import mitt from 'mitt'
const eventBus = mitt()
export default eventBus
  1. 自定义数据仓库:其实就是简易版的 Pinia.
  2. Pinia

文章作者: 吴俊杰
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 吴俊杰 !
 上一篇
一、React Diff 算法的源码应该怎么读 一、React Diff 算法的源码应该怎么读
源码生涩难懂,但是一定要去读不要怕,要学会从战略上蔑视它,从战术上重视它,总有一天你会觉得React diff和fiber架构它并不难......
下一篇 
四十四、动态路由 四十四、动态路由
vue3相对vue2看似改了很多东西,但其实很多底层的原理都还是一样的不用怕,我们先来看看动态路由吧......
2024-12-06
  目录