Vue2-Vue3组件间通信-EventBus方式-函数封装
Vue3中采用EventBus方式进行组件间通信与Vue2有一定区别
1.创建EventBus
在Vue2中,我们可以在main.js中创建一个全局的EventBus,代码如下:
// EventBus.js
import Vue from 'vue'
const EventBus = new Vue()
export default EventBus
// main.js
import EventBus from './EventBus'
Vue.prototype.$bus = EventBus
在Vue3中,我们需要使用createApp来创建Vue实例,并使用provide和inject来创建全局的EventBus,代码如下:
// EventBus.js
import { createApp } from 'vue'
const app = createApp({})
const EventBus = app.provide('EventBus', new app())
export default EventBus
// main.js
import EventBus from './EventBus'
createApp(App).use(EventBus).mount('#app')
-----------------
// 在 main.js 或入口文件中
import { createApp, provide } from 'vue';
import App from './App.vue';
const app = createApp(App);
const eventBus = createApp({});
// 将 eventBus 实例作为提供者提供给子组件
app.provide('eventBus', eventBus);
app.mount('#app');
2.使用EventBus进行通信
在Vue2中,我们可以通过$emit和$on方法来进行通信,代码如下:
// 发送通信
this.$emit('event', data)
// 接收通信
this.$on('event', (data) => {
console.log(data)
})
// 销毁
this.$off('event')
在Vue3中,我们可以通过$emit和$on方法来进行通信,但是需要在组件中使用AppContext来获取EventBus,代码如下:
// 发送通信
const app = getCurrentInstance().appContext.app
app.config.globalProperties.$EventBus.emit('event', data)
// 接收通信
const app = getCurrentInstance().appContext.app
app.config.globalProperties.$EventBus.on('event', (data) => {
console.log(data)
})
// 销毁
const app = getCurrentInstance().appContext.app
app.config.globalProperties.$EventBus.off('event')
-------------------
import { inject } from 'vue';
export default {
// ...
created() {
const eventBus = inject('eventBus');
// 使用 eventBus 进行事件的发布和订阅
},
// ...
}
总的来说,Vue3与Vue2在EventBus方式上的区别不大,只是在创建全局EventBus的方式上有所不同,但是使用起来差异较大,需要根据实际情况进行选择。
封装EventBus.js
类方式
class Event {
constructor() {
this.queue = {};
this.onceQueue = {};
}
$on(name, callback) {
this.queue[name] = this.queue[name] || [];
this.queue[name].push(callback);
}
$once(name, callback) {
this.onceQueue[name] = this.onceQueue[name] || [];
this.onceQueue[name].push(callback);
}
$off(name, callback) {
if (callback) {
if (this.queue[name]) {
for (var i = 0; i < this.queue[name].length; i++) {
if (this.queue[name][i] === callback) {
this.queue[name].splice(i, 1);
break;
}
}
}
} else {
delete this.queue[name];
}
}
$emit(name, data) {
if (this.queue[name]) {
this.queue[name].forEach(function (callback) {
callback(data);
});
}
if (this.onceQueue[name]) {
this.onceQueue[name].forEach(function (callback) {
callback(data);
});
delete this.onceQueue[name];
}
}
}
export default new Event();
使用
import Bus from '@/utils/EventBus';
Bus.$on('test', (data) => {})
Bus.$emit('close')
beforeUnmount() {
Bus.$off('test', fun)
}
构造函数方式
function E() { }
// 函数E的原型对象
E.prototype = {
// on方法:接受订阅名,订阅函数,上下文对象
on: function (name, callback, context) {
// 初始化e仓库
var e = this.e || (this.e = {})
// 收集订阅函数
// 包装为对象,收集订阅函数与上下文对象
; (e[name] || (e[name] = [])).push({
fn: callback,
context
})
// 返回实例对象
return this
},
// once函数:接收订阅名,订阅函数,上下文对象
// 与on的区别是:once函数收集只执行一遍的订阅函数
once: function (name, callback, context) {
let self = this
// 包装对象,用于自定义执行逻辑(删除操作)
function listener() {
self.off(name, listener)
callback.apply(context, arguments)
}
// 保存原始函数
listener._ = callback
// 使用on收集自定义后的函数
// 执行on方法会返回this,所以once函数内不需要返回this
return this.on(name, listener, context)
},
// emit方法用于触发订阅函数:接收订阅名称
emit: function (name) {
// 收集参数
let args = [].slice.call(arguments, 1)
// 收集订阅函数数组
let events = ((this.e || (this.e = {}))[name] || []).slice()
let i = 0
let len = events.length
// 循环执行订阅函数
for (; i < len; i++) {
// 使用apply调用函数并绑定this
events[i].fn.apply(events[i].context, args)
}
// 返回this实例
return this
},
// off用于删除订阅函数:接收订阅名和订阅函数
off: function (name, callback) {
let e = this.e || (this.e = {})
// 获取订阅名称对应的数组
let events = e[name]
let liveEvents = []
// 处理函数数组&传入的订阅函数是否都存在?
if (events && callback) {
// 循环遍历,过滤操作
for (let i = 0, len = events.length; i < len; i++) {
// 判断数组中的订阅函数是否与传入的订阅函数相等?
// 使用once创建的函数取_属性中的原始函数进行对比
if (events[i].fn !== callback && events[i].fn._ !== callback) {
liveEvents.push(events[i])
}
}
}
// 重置订阅名结果数组
(liveEvents.length) ? e[name] = liveEvents : delete e[name]
// 返回实例this
return this
}
}
export default {
$on: (...args) => E.prototype.on(...args),
$once: (...args) => E.prototype.once(...args),
$off: (...args) => E.prototype.off(...args),
$emit: (...args) => E.prototype.emit(...args)
}
使用
import Bus from "@/utils/EventBus2";
Bus.$on('test', (data) => {})
Bus.$emit('close')
beforeUnmount() {
Bus.$off('test', fun)
}
本文来自博客园,作者:JackieDYH,转载请注明原文链接:https://www.cnblogs.com/JackieDYH/p/17634008.html