Vue 父子跨级通讯 dispatch与broadcast

编程入门 行业动态 更新时间:2024-10-26 06:31:43

Vue <a href=https://www.elefans.com/category/jswz/34/1769150.html style=父子跨级通讯 dispatch与broadcast"/>

Vue 父子跨级通讯 dispatch与broadcast

.html

技术没有好与坏,只有合适不合适

问题

为什么被移除

  1. 没有解决兄弟组件的通信问题
  2. 事件流动的方式是基于组件树结构的,当业务越来越烦杂时会混乱到难以维护

为什么使用

  • 解决在父子层嵌套组件
  • 通过$dispatch和broadcast定向的向某个父或者子组件远程调用事件,这样就避免了通过传props或者使用refs调用组件实例方法的操作。

代码

// Vue
/*** Recursively broadcast an event to all children instances.* 递归地向所有子实例广播事件。* @param {String|Object} event* @param {...*} additional arguments*/
// $dispatch 方法是定义在 Vue 的 prototype 上的
// 接受一个事件
Vue.prototype.$broadcast = function (event) {// 获取传入事件的类型,判断是否为字符串var isSource = typeof event === 'string'// 校正 event 的值,当接受 event 的类型为字符串时就直接使用,如果不是字符串就使用 event 上的 name 属性 event = isSource ? event : event.name// if no child has registered for this event,// then there's no need to broadcast.// 如果当前组件的子组件没有注册该事件,就直接返回,并不用 broadcastif (!this._eventsCount[event]) return// 获取当前组件的子组件var children = this.$children// 将函数接受的参数转换成数组var args = toArray(arguments)// 如果传入事件为字符串if (isSource) {// use object event to indicate non-source emit// on children// 根据传入的事件名称的参数组装成 objectargs[0] = { name: event, source: this }}// 循环子组件for (var i = 0, l = children.length; i < l; i++) {var child = children[i]// 在每个子组件中调用 $emit 触发事件var shouldPropagate = child.$emit.apply(child, args)// 判断调用 $emit 返回的值是否为 trueif (shouldPropagate) {// 如果调用 $emit 返回的值为 true,就递归孙子组件继续广播child.$broadcast.apply(child, args)}}// 最后返回当前组件的实例return this
}
// element-ui
/*** 派发和广播* 核心思想是通过递归或遍历来查找要broadcast或dispatch的组件名字,然后在组件自身上emit与on* @param {*} componentName 需要触发事件的组件名称* @param {*} eventName 将要触发的事件名称* @param {*} params 回调函数传递的参数*/
function broadcast(componentName, eventName, params) {this.$children.forEach(child => {var name = child.$optionsponentName;if (name === componentName) {child.$emit.apply(child, [eventName].concat(params));} else {broadcast.apply(child, [componentName, eventName].concat([params]));}});
}
export default {methods: {dispatch(componentName, eventName, params) {var parent = this.$parent || this.$root;var name = parent.$optionsponentName;while (parent && (!name || name !== componentName)) {parent = parent.$parent;if (parent) {name = parent.$optionsponentName;}}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>

更多推荐

Vue 父子跨级通讯 dispatch与broadcast

本文发布于:2024-02-17 08:13:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1693289.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:父子   通讯   Vue   dispatch   broadcast

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!