Vue2组件通信 - dispatch 和 broadcast

2023-09-21 22:28:33

承接文章 Vue2中10种组件通信方式和实践技巧,因为一篇文章太长无法发表,所以做拆分。

8,dispatch 和 broadcast

在 Vue@1 版本中,有 $dispatch$broadcast 这种基于组件树的工作流来通信。缺点是项目变复杂后,结构扩展的过程中会变得越来越难维护,所以被废弃了。

整体思路

本质上还是 $on()$emit() 监听和触发事件。

关键点:$emit() 触发的是实例自己通过 $on() 监听的事件。

1,dispatch 是向任意指定的祖先组件通信。

实现思路:先在指定的祖先组件中使用 this.$on() 监听事件 eventParent。后代组件需要触发祖先组件监听的事件 eventParent 时,层层向上找到指定的祖先组件,通过 $emit() 触发监听的事件。

2,broadcast 是向任意指定的后代组件通信。

实现思路,先在指定的后代组件中使用 this.$on() 监听事件 event1。父组件需要触发后代组件监听的事件 event1 时,会递归遍历子组件找到指定的后代组件,通过 $emit() 触发监听的事件。

实现

element-ui 的实现

element-ui 是基于自己的考虑来使用的,比如表单组件的传参验证等,基于组件树但层级不深并且可控。

// 因为会被递归调用,所以写到外面
function broadcast(componentName, eventName, params) {
  this.$children.forEach((child) => {
    var name = child.$options.componentName; // componentName 是约定的组件标识

    if (name === componentName) {
      child.$emit.apply(child, [eventName].concat(params));
    } else {
      // 递归调用
      broadcast.apply(child, [componentName, eventName].concat([params]));
    }
  });
}
export default {
  methods: {
    dispatch(componentName, eventName, params) {
      var parent = this.$parent || this.$root;
      var name = parent.$options.componentName; // componentName 是约定的组件标识

      while (parent && (!name || name !== componentName)) {
        parent = parent.$parent;

        if (parent) {
          name = parent.$options.componentName;
        }
      }
      if (parent) {
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    },
    broadcast(componentName, eventName, params) {
      broadcast.call(this, componentName, eventName, params);
    },
  },
};

dispatch 使用举例

A<–B<–C(A是祖先组件)

// 触发祖先组件 A 的 eventParent 事件,并传参 123
this.dispatch('A', 'eventParent', 123)

举例:

<!-- A组件 -->
<template>
  <BComponent />
</template>

<script>
import BComponent from "./components/B.vue";
export default {
  componentName: "A",
  components: {
    BComponent,
  },
  methods: {
    methodParent(item) {
      console.log(item);
    },
  },
  created() {
    this.$on("eventParent", this.methodParent);
  },
};
</script>
<!-- B组件 -->
<template>
  <CComponent />
</template>

<script>
import CComponent from "./C.vue";
export default {
  components: {
    CComponent,
  },
};
</script>
<!-- C组件 -->
<template>
  <button @click="handleClick">触发祖先组件A的方法</button>
</template>

<script>
import Emitter from "@/mixins/emitter.js";
export default {
  mixins: [Emitter],
  methods: {
    handleClick() {
      this.dispatch("A", "eventParent", 123);
    },
  },
};
</script>

broadcast 使用举例

A<–B<–C(A是祖先组件)

// 触发后代组件 C 的 eventChild 事件,并传参 123
this.broadcast('C', 'eventChild', 123)

举例,

<!-- A组件 -->
<template>
  <div>
    <BComponent />
    <button @click="handleClick">触发后台组件C的方法</button>
  </div>
</template>

<script>
import BComponent from './components/B.vue'
import Emitter from '@/mixins/emitter.js'
export default {
  components: {
    BComponent
  },
  mixins: [Emitter],
  methods: {
    handleClick() {
      this.broadcast('C', 'eventChild', 123) // 会触发 eventChild 事件绑定的2个处理函数。
    }
  }
}
</script>
<!-- B组件 -->
<template>
  <CComponent />
</template>

<script>
import CComponent from './C.vue'
export default {
  components: {
    CComponent
  }
}
</script>
<!-- C组件 -->
<template></template>

<script>
export default {
  componentName: 'C',
  methods: {
    methodC1(item) {
      console.log(item)
    },
    methodC2(item) {
      console.log(item)
    }
  },
  created() {
    this.$on('eventChild', this.methodC1)
    this.$on('eventChild', this.methodC2)
  }
}
</script>

以上。

更多推荐

数据结构和算法之快速排序

快速排序是一种基于分治法的排序算法。它通过不断地将数组分成较小的子数组,并按照递归的方式对每个子数组进行排序,最终将整个数组排序。#mermaid-svg-Za26UnuASULzGzsM{font-family:"trebuchetms",verdana,arial,sans-serif;font-size:16px

Vue路由与nodejs环境搭建

一.路由什么是路由什么是SPA路由的思路及实现实例建立一个HTML来编写路由测试结果​编辑二.nodejs环境什么是node.jsnpm是什么node.js的下载一.路由什么是路由路由(Routing)是指根据不同的URL地址,将用户导航到不同的页面或视图的过程。在前端开发中,特别是在单页面应用(SPA)中,路由起着至

Python实现MYSQL蜜罐

1LOADDATAINFILE介绍首先开启一个Mysql,看一下mysql是如何读取主机文件的。1.1linux搭建mysql1)docker运行mysql2)启动Mysqldockerrun-itd--namemysql-p3306:3306-eMYSQL_ROOT_PASSWORD=123456mysql3)进入容

Rust常见编程概念

变量和可变性rust使用let声明变量,变量默认是不可改变的。通过在let后面加上mut,可以声明可变变量。可以在变量名后加:和类型名,来显式声明变量类型,例如:leta:u32=1;常量常量使用const声明,变量名一般约定使用大写。隐藏不同的作用域如果有重叠,且重叠区域内有同名的变量,那么更小的作用域里变量会隐藏外

CentOS 7系统安装与配置、常用100条操作命令

CentOS7是一个广泛使用的开源Linux操作系统,它是RedHatEnterpriseLinux(RHEL)的一个免费重建版本,以稳定性和安全性而著称。在CentOS7上安装虚拟机通常使用虚拟化技术,如VirtualBox或VMware等。以下是CentOS7的简要介绍以及如何安装CentOS7虚拟机的步骤。Cen

git 的文件目录错误删除 --chatGPT

问:git的文件目录错误删除,需要还原到最后一次提交的位置,如何操作gpt:如果您在Git中删除了文件或目录,想要还原到最后一次提交的位置,可以使用以下步骤:1.**查看Git状态**:首先,可以使用以下命令来查看当前Git仓库的状态,以确保您删除了哪些文件或目录:```gitstatus```这将列出未提交的更改,包

(python语言程序设计教程)自学二

(python语言程序设计教程)自学二文章目录前言一、编写简单的程序1.1.标识符及命名规则1.2.变量与赋值语句1.3.数值1.4.字符串二、turtle画图2.1.绘制爱心并书写文本2.2.绘制幸运的四叶草2.3.浪漫的玫瑰花三、课后习题总结前言本系列文章,主要是对学校开设的python课程进行总结,教科书为:py

性能测试 —— 性能测试常见的测试指标 !

一、什么是性能测试先看下百度百科对它的定义,性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。我们可以认为性能测试是:通过在测试环境下对系统或构件的性能进行探测,用以验证在生产环境下系统性能是否达到预估的性能需求,发现系统可能存在的性能瓶颈,进而改善优化并系统的性能,提高系

多线程的上下文切换

多线程的上下文切换是指在多线程环境下,操作系统或调度器将CPU执行权从一个线程切换到另一个线程的过程。上下文切换允许多个线程交替执行,使得看起来多个线程同时在运行,从而实现并发性。上下文切换的发生通常有以下几种情况:时间片耗尽:操作系统为每个线程分配一定的时间片(或时间量),当一个线程的时间片用尽时,操作系统会暂停该线

【面试题精讲】如何将二进制转为十六进制

有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址文章更新计划系列文章地址/***二进制转换为十六进制*这里主要用于处理图片数据,因为数据库存储了图片的Base64编码*/privateStringbytesToHexString(by

CVPR 2023 | UniMatch: 重新审视半监督语义分割中的强弱一致性

在这里和大家分享一下我们被CVPR2023录用的工作"RevisitingWeak-to-StrongConsistencyinSemi-SupervisedSemanticSegmentation"。在本工作中,我们重新审视了半监督语义分割中的“强弱一致性”方法。我们首先发现,最基本的约束强弱一致性的方法FixMat

热文推荐