详解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+iview实现分页及查询功能
Nov 17 Vue.js
vue+element实现动态加载表单
Dec 13 Vue.js
vue实现登录功能
Dec 31 Vue.js
vue实现一个获取按键展示快捷键效果的Input组件
Jan 13 Vue.js
详解实现vue的数据响应式原理
Jan 20 Vue.js
使用vue3重构拼图游戏的实现示例
Jan 25 Vue.js
Vue常用API、高级API的相关总结
Feb 02 Vue.js
如何管理Vue中的缓存页面
Feb 06 Vue.js
手写Vue2.0 数据劫持的示例
Mar 04 Vue.js
Vue.js中v-bind指令的用法介绍
Mar 13 Vue.js
vue如何清除浏览器历史栈
May 25 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
mysql 字段类型说明
2007/04/27 PHP
php 文章采集正则代码
2009/12/28 PHP
Zend Framework教程之Zend_Db_Table_Row用法实例分析
2016/03/21 PHP
laravel 5.3中自定义加密服务的方案详解
2017/05/09 PHP
thinkPHP事务操作简单案例分析
2019/10/17 PHP
javascript 写类方式之三
2009/07/05 Javascript
Textarea与懒惰渲染实现代码
2012/01/04 Javascript
通过javascript把图片转化为字符画
2013/10/24 Javascript
Mac/Windows下如何安装Node.js
2013/11/22 Javascript
javascript面向对象快速入门实例
2015/01/13 Javascript
javascript实现下班倒计时效果的方法(可桌面通知)
2015/07/10 Javascript
json+jQuery实现的无限级树形菜单效果代码
2015/08/27 Javascript
JavaScript中匿名函数的用法及优缺点详解
2016/06/01 Javascript
jQuery将表单序列化成一个Object对象的实例
2016/11/29 Javascript
jQuery控制元素隐藏和显示
2017/03/03 Javascript
webpack配置导致字体图标无法显示的解决方法
2018/03/06 Javascript
vue.js中$set与数组更新方法
2018/03/08 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
2018/09/26 Javascript
JS遍历树层级关系实现原理解析
2020/08/31 Javascript
[02:38]DOTA2超级联赛专访Loda 认为IG世界最强
2013/05/27 DOTA
[01:02:02]DOTA2上海特级锦标赛A组败者赛 EHOME VS CDEC第二局
2016/02/25 DOTA
使用python的chardet库获得文件编码并修改编码
2014/01/22 Python
仅利用30行Python代码来展示X算法
2015/04/01 Python
Python获取linux主机ip的简单实现方法
2016/04/18 Python
对Python3 解析html的几种操作方式小结
2019/02/16 Python
Python日期时间Time模块实例详解
2019/04/15 Python
OpenCV-Python 摄像头实时检测人脸代码实例
2019/04/30 Python
python os模块简单应用示例
2019/05/23 Python
HTML5 自动聚焦(autofocus)属性使用介绍
2013/08/07 HTML / CSS
HTML5 图片预加载的示例代码
2020/03/25 HTML / CSS
美国领先的在线旅游网站:Orbitz
2018/11/05 全球购物
AutoShack.com加拿大:北美主要的汽车零部件零售商
2019/07/24 全球购物
财务会计应届生求职信
2013/11/24 职场文书
精神病医院见习报告
2014/11/03 职场文书
贷款工资证明范本
2015/06/12 职场文书
2015年网络舆情工作总结
2015/07/24 职场文书