详解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单元格多列合并的实现
Nov 26 Vue.js
vue从后台渲染文章列表以及根据id跳转文章详情详解
Dec 14 Vue.js
vue 导航守卫和axios拦截器有哪些区别
Dec 19 Vue.js
vue keep-alive的简单总结
Jan 25 Vue.js
vue实现桌面向网页拖动文件的示例代码(可显示图片/音频/视频)
Mar 01 Vue.js
使用vue-element-admin框架从后端动态获取菜单功能的实现
Apr 29 Vue.js
Vue监视数据的原理详解
Feb 24 Vue.js
一起来看看Vue的核心原理剖析
Mar 24 Vue.js
vue使用refs获取嵌套组件中的值过程
Mar 31 Vue.js
vue实力踩坑之push当前页无效
Apr 10 Vue.js
vue项目配置sass及引入外部scss文件
Apr 14 Vue.js
Vue2项目中对百度地图的封装使用详解
Jun 16 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
php checkbox 取值详细说明
2010/08/19 PHP
php session实现多级目录存放实现代码
2016/02/03 PHP
PHP函数积累总结
2019/03/19 PHP
tp5(thinkPHP5框架)时间查询操作实例分析
2019/05/29 PHP
如何用javascript去掉字符串里的所有空格
2007/02/08 Javascript
JS关键字变色实现思路及代码
2013/02/21 Javascript
JS对img进行操作(换图片/切图/轮换/停止)
2013/04/17 Javascript
使用jQuery快速解决input中placeholder值在ie中无法支持的问题
2014/01/02 Javascript
JS+CSS实现电子商务网站导航模板效果代码
2015/09/10 Javascript
javascript省市级联功能实现方法实例详解
2015/10/20 Javascript
js+html5实现canvas绘制椭圆形图案的方法
2016/05/21 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
2016/12/26 Javascript
解决iview打包时UglifyJs报错的问题
2018/03/07 Javascript
Vue 开发必须知道的36个技巧(小结)
2019/10/09 Javascript
vue获取form表单的值示例
2019/10/29 Javascript
vue实现在进行增删改操作后刷新页面
2020/08/05 Javascript
[52:57]2014 DOTA2国际邀请赛中国区预选赛 LGD-CDEC VS HGT
2014/05/21 DOTA
[01:32]2014DOTA2西雅图邀请赛 CIS我们有信心进入正赛
2014/07/08 DOTA
Python的time模块中的常用方法整理
2015/06/18 Python
python万年历实现代码 含运行结果
2017/05/20 Python
基于Django的python验证码(实例讲解)
2017/10/23 Python
Python实现统计给定字符串中重复模式最高子串功能示例
2018/05/16 Python
基于anaconda下强大的conda命令介绍
2018/06/11 Python
Django后端发送小程序微信模板消息示例(服务通知)
2019/12/17 Python
Python tkinter三种布局实例详解
2020/01/06 Python
pytorch实现建立自己的数据集(以mnist为例)
2020/01/18 Python
导致python中import错误的原因是什么
2020/07/01 Python
奥地利网上现代灯具和灯饰店:Lampenwelt.at
2018/01/29 全球购物
Fossil美国官网:化石手表、手袋、首饰及配饰
2019/02/17 全球购物
澳大利亚家具商店:Freedom
2020/12/17 全球购物
韩语专业本科生求职信
2013/10/01 职场文书
电子信息工程专业自荐书
2014/06/24 职场文书
党支部四风整改方案
2014/10/25 职场文书
化验员岗位职责
2015/02/14 职场文书
团员自我评价范文
2015/03/10 职场文书
Keras多线程机制与flask多线程冲突的解决方案
2021/05/28 Python