详解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 01 Vue.js
基于Vue3.0开发轻量级手机端弹框组件V3Popup的场景分析
Dec 30 Vue.js
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
Jan 05 Vue.js
Vue项目打包部署到apache服务器的方法步骤
Feb 01 Vue.js
学习 Vue.js 遇到的那些坑
Feb 02 Vue.js
vue中h5端打开app(判断是安卓还是苹果)
Feb 26 Vue.js
详解vue3中组件的非兼容变更
Mar 03 Vue.js
vue配置型表格基于el-table拓展之table-plus组件
Apr 12 Vue.js
vue2的 router在使用过程中遇到的一些问题
Apr 13 Vue.js
vue项目打包后路由错误的解决方法
Apr 13 Vue.js
vue使用localStorage持久性存储实现评论列表
Apr 14 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
提问的智慧(2)
2006/10/09 PHP
YII模块实现绑定二级域名的方法
2014/07/09 PHP
thinkphp3.x中cookie方法的用法分析
2016/05/19 PHP
关于js获取radio和select的属性并控制的代码
2011/05/12 Javascript
javascript学习笔记(十九) 节点的操作实现代码
2012/06/20 Javascript
js中apply方法的使用详细解析
2013/11/04 Javascript
JQuery select(下拉框)操作方法汇总
2015/04/15 Javascript
JQuery实现超链接鼠标提示效果的方法
2015/06/10 Javascript
JavaScript中的toDateString()方法使用详解
2015/06/12 Javascript
JavaScript实现的类字典插入或更新方法实例
2015/07/10 Javascript
基于javascript实现图片滑动效果
2016/05/07 Javascript
简单实现jQuery进度条轮播实例代码
2016/06/20 Javascript
JS实现的DIV块来回滚动效果示例
2017/02/07 Javascript
javascript定时器取消定时器及优化方法
2017/07/08 Javascript
详解react-redux插件入门
2018/04/19 Javascript
nodejs 日志模块winston的使用方法
2018/05/02 NodeJs
解决Vue在封装了Axios后手动刷新页面拦截器无效的问题
2018/11/08 Javascript
uni-app从安装到卸载的入门教程
2020/05/15 Javascript
Python Web框架Tornado运行和部署
2020/10/19 Python
Python实现树的先序、中序、后序排序算法示例
2017/06/23 Python
浅谈python数据类型及类型转换
2017/12/18 Python
python实现字符串和字典的转换
2018/09/29 Python
对python借助百度云API对评论进行观点抽取的方法详解
2019/02/21 Python
Python Excel处理库openpyxl使用详解
2019/05/09 Python
Python3.5 + sklearn利用SVM自动识别字母验证码方法示例
2019/05/10 Python
python机器学习包mlxtend的安装和配置详解
2019/08/21 Python
python用WxPython库实现无边框窗体和透明窗体实现方法详解
2020/02/21 Python
Python如何使用ElementTree解析xml
2020/10/12 Python
matplotlib绘制正余弦曲线图的实现
2021/02/22 Python
一波HTML5 Canvas基础绘图实例代码集合
2016/02/28 HTML / CSS
专科毕业生就业推荐信
2013/11/01 职场文书
开办加工厂创业计划书
2014/01/03 职场文书
《回乡偶书》教学反思
2014/04/12 职场文书
2014年村支部书记四风对照检查材料思想汇报
2014/10/02 职场文书
幼儿园教师管理制度
2015/08/05 职场文书
十大最强奥特曼武器:怪兽战斗仪在榜,第五奥特之父只使用过一次
2022/03/18 日漫