详解vue之自行实现派发与广播(dispatch与broadcast)


Posted in Vue.js onJanuary 19, 2021

要解决的问题

主要针对组件之间的跨级通信

为什么要自己实现dispatch与broadcast?

因为在做独立组件开发或库时,最好是不依赖第三方库

为什么不使用provide与inject?

因为它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
然后有两种场景它不能很好的解决:
父组件向子组件(支持跨级)传递数据;
子组件向父组件(支持跨级)传递数据。

代码如下:

emitter.js

function broadcast(componentName, eventName, params) {
 this.$children.forEach(child => {
  const name = child.$options.name;

  if (name === componentName) {
   child.$emit.apply(child, [eventName].concat(params));
  } else {
   // todo 如果 params 是空数组,接收到的会是 undefined
   broadcast.apply(child, [componentName, eventName].concat([params]));
  }
 });
}
export default {
 methods: {
  dispatch(componentName, eventName, params) {
   let parent = this.$parent || this.$root;
   let name = parent.$options.name;

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

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

parent.vue

<template>
 <div>
  <h1>我是父组件</h1>
  <button @click="handleClick">触发事件</button> <child />
 </div>
</template>
<script>
import Emitter from "@/mixins/emitter.js";
import Child from "./child";
export default {
 name: "componentA",
 mixins: [Emitter],
 created() {
  this.$on("child-to-p", this.handleChild);
 },
 methods: {
  handleClick() {
   this.broadcast("componentB", "on-message", "Hello Vue.js");
  },
  handleChild(val) {
   alert(val);
  }
 },
 components: {
  Child
 }
};
</script>

child.vue

<template>
 <div>我是子组件</div>
</template>
<script>
import Emitter from "@/mixins/emitter.js";
export default {
 name: "componentB",
 mixins: [Emitter],
 created() {
  this.$on("on-message", this.showMessage);
  this.dispatch("componentA", "child-to-p", "hello parent");
 },
 methods: {
  showMessage(text) {
   window.alert(text);
  }
 }
};
</script>

这样就能实现跨级组件自定义通信了,但是,要注意其中一个问题:订阅必须先于发布,也就是说先有on再有emit

父子组件渲染顺序,实例创建顺序

子组件先于父组件前渲染,所以在子组的mounted派发事件时,在父组件中的mounte中是监听不到的。
而父组件的create是先于子组件的,所以可以在父组件中的create可以监听到

到此这篇关于详解vue之自行实现派发与广播(dispatch与broadcast)的文章就介绍到这了,更多相关vue 派发与广播内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
Vue实现省市区三级联动
Dec 27 Vue.js
vue导入.md文件的步骤(markdown转HTML)
Dec 31 Vue.js
vue实现禁止浏览器记住密码功能的示例代码
Feb 03 Vue.js
vue 使用 v-model 双向绑定父子组件的值遇见的问题及解决方案
Mar 01 Vue.js
vue使用v-model进行跨组件绑定的基本实现方法
Apr 28 Vue.js
Vue详细的入门笔记
May 10 Vue.js
vue+element ui实现锚点定位
Jun 29 Vue.js
vue+echarts实现多条折线图
Mar 21 Vue.js
分享一个vue实现的记事本功能案例
Apr 11 Vue.js
如何优化vue打包文件过大
Apr 13 Vue.js
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
Apr 30 Vue.js
vue使用element-ui按需引入
May 20 Vue.js
vue二选一tab栏切换新做法实现
Jan 19 #Vue.js
vue-resource 拦截器interceptors使用详解
Jan 18 #Vue.js
vue element el-transfer增加拖拽功能
Jan 15 #Vue.js
Vue实现多页签组件
Jan 14 #Vue.js
如何在vue中使用HTML 5 拖放API
Jan 14 #Vue.js
Vue中引入svg图标的两种方式
Jan 14 #Vue.js
vue+element table表格实现动态列筛选的示例代码
Jan 14 #Vue.js
You might like
PHPlet在Windows下的安装
2006/10/09 PHP
深入密码加salt原理的分析
2013/06/06 PHP
学习php设计模式 php实现享元模式(flyweight)
2015/12/07 PHP
PHP入门教程之PHP操作MySQL的方法分析
2016/09/11 PHP
laravel5使用freetds连接sql server的方法
2018/12/07 PHP
Js中sort()方法的用法
2006/11/04 Javascript
Javascript 模式实例 观察者模式
2009/10/24 Javascript
JQuery扩展插件Validate 1 基本使用方法并打包下载
2011/09/05 Javascript
JavaScript中的分号插入机制详细介绍
2015/02/11 Javascript
基于javascript实现动态显示当前系统时间
2016/01/28 Javascript
JS中正则表达式全局匹配模式 /g用法详解
2017/04/01 Javascript
Angular.js中控制器之间的传值详解
2017/04/24 Javascript
Node.js pipe实现源码解析
2017/08/12 Javascript
浅谈AngularJS中使用$resource(已更新)
2017/09/14 Javascript
解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题
2018/09/14 Javascript
利用weixin-java-miniapp生成小程序码并直接返回图片文件流的方法
2019/03/29 Javascript
js与jquery获取input输入框中的值实例讲解
2020/02/27 jQuery
Vue向后台传数组数据,springboot接收vue传的数组数据实例
2020/11/12 Javascript
python实现堆栈与队列的方法
2015/01/15 Python
Python多线程下载文件的方法
2015/07/10 Python
Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程
2016/06/14 Python
Python入门学习指南分享
2018/04/11 Python
pandas 根据列的值选取所有行的示例
2018/11/07 Python
python多线程抽象编程模型详解
2019/03/20 Python
Python中低维数组填充高维数组的实现
2019/12/02 Python
在keras下实现多个模型的融合方式
2020/05/23 Python
解决运行django程序出错问题 'str'object has no attribute'_meta'
2020/07/15 Python
Python抖音快手代码舞(字符舞)的实现方法
2021/02/07 Python
全球500多个机场的接送服务:Suntransfers
2019/06/03 全球购物
致跳远、跳高运动员广播稿
2014/01/09 职场文书
2015入党自荐书范文
2015/03/05 职场文书
学生犯错保证书
2015/05/09 职场文书
离婚被告答辩状
2015/05/22 职场文书
大学生十八大感想
2015/08/11 职场文书
一文搞懂Python Sklearn库使用
2021/08/23 Python
Nginx如何配置根据路径转发详解
2022/07/23 Servers