详解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实现表格合并功能
Dec 01 Vue.js
vue3.0+vue-router+element-plus初实践
Dec 02 Vue.js
如何实现vue的tree组件
Dec 03 Vue.js
利用Vue实现简易播放器的完整代码
Dec 30 Vue.js
vue中activated的用法
Jan 03 Vue.js
如何封装Vue Element的table表格组件
Feb 06 Vue.js
VUE实现吸底按钮
Mar 04 Vue.js
vue前端工程的搭建
Mar 31 Vue.js
vue项目两种方式实现竖向表格的思路分析
Apr 28 Vue.js
一定要知道的 25 个 Vue 技巧
Nov 02 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
PHP实现多条件查询实例代码
2010/07/17 PHP
php下网站防IP攻击代码,超级实用
2010/10/24 PHP
如何使用jQuery+PHP+MySQL来实现一个在线测试项目
2015/04/26 PHP
PHP命名空间简单用法示例
2018/12/28 PHP
分享27款非常棒的jQuery 表单插件
2011/03/28 Javascript
基于jquery的滚动鼠标放大缩小图片效果
2011/10/27 Javascript
js渐变显示渐变消失示例代码
2013/08/01 Javascript
js判断iframe内的网页是否滚动到底部触发事件
2014/03/18 Javascript
jQuery实现平滑滚动到指定锚点的方法
2015/03/20 Javascript
举例讲解JavaScript中将数组元素转换为字符串的方法
2015/10/25 Javascript
jquery实现两边飘浮可关闭的对联广告
2015/11/27 Javascript
深入分析Javascript事件代理
2016/01/30 Javascript
浅谈JavaScript的闭包函数
2016/12/08 Javascript
详解JavaScript时间处理之几个月前或几个月后的指定日期
2016/12/21 Javascript
JS前端加密算法示例
2016/12/22 Javascript
javascript 中Cookie读、写与删除操作
2017/03/29 Javascript
JavaScript方法_动力节点Java学院整理
2017/06/28 Javascript
带你快速理解javascript中的事件模型
2017/08/14 Javascript
vue2.0 实现页面导航提示引导的方法
2018/03/13 Javascript
JS原型与继承操作示例
2019/05/09 Javascript
如何让微信小程序页面之间的通信不再变困难
2019/06/03 Javascript
深入理解 TypeScript Reflect Metadata
2019/12/12 Javascript
vue+AI智能机器人回复功能实现
2020/07/16 Javascript
简介Django框架中可使用的各类缓存
2015/07/23 Python
Python版名片管理系统
2018/11/30 Python
python实现静态服务器
2019/09/05 Python
Pytorch 实现focal_loss 多类别和二分类示例
2020/01/14 Python
Python telnet登陆功能实现代码
2020/04/16 Python
CSS3实现瀑布流布局与无限加载图片相册的实例代码
2016/12/22 HTML / CSS
HTML 5 input placeholder 属性如何完美兼任ie
2014/05/12 HTML / CSS
美国体育用品商店:Paragon Sports
2017/10/08 全球购物
大学运动会加油稿200字(5篇)
2014/09/27 职场文书
森马旗舰店双十一营销方案
2014/09/29 职场文书
基层党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
个人收入证明范本
2015/06/12 职场文书
Windows server 2022创建创建林、域树、子域的步骤
2022/06/25 Servers