本章我们将聊到一个重点,在Vue3.x中实现全局通讯。
1、前言:由于Vue3.x中删除了off,因此不能借助于一个单独的Vue实例来实现全局事件的发布和订阅与取消订阅(也就是跨组件通讯)。
2、概述:mitt是一个三方库,npm安装:npm install -D mitt
3、使用:我们以同样使用插件的方式将mitt集成到Vue中。
4、mitt对象:
- all(Map对象):包含了所有订阅的事件名称,及对应的处理方法数组。
- emit(方法):触发事件,参数为(事件名(方法名),携带的参数),当- 前携带的参数只能为一个,不能为多个。
- on(方法):创建事件订阅,参数为(事件名,处理方法)。
- off(方法):取消事件订阅,参数为(事件名,处理方法)。
5、全局事件总成搭建:
import _ from 'lodash';
import mitt from 'mitt';
export default {
install(Vue, options) {
const _emitter = mitt();
// 全局发布(在Vue全局方法中自定义$pub发布方法)
// 这里做了$pub方法能够携带多个参数的处理,方便我们再业务中触发事件时带多个参数
Vue.config.globalProperties.$pub = (...args) => {
_emitter.emit(_.head(args), args.slice(1));
};
// 全局订阅(在Vue全局方法中自定义$sub订阅方法)
Vue.config.globalProperties.$sub = function (event, callback) {
Reflect.apply(_emitter.on, _emitter, _.toArray(arguments));
};
// 取消订阅
Vue.config.globalProperties.$unsub = function (event, callback) {
Reflect.apply(_emitter.off, _emitter, _.toArray(arguments));
};
}
};
6、组件实例中使用:
全局事件发布
<template>
<div class="child">
<button @click="pubHandler">发起事件</button>
</div>
</template>
<script>
import { onMounted, getCurrentInstance } from 'vue';
export default {
setup(props, context) {
const { proxy } = getCurrentInstance();
const pubHandler = () => {
proxy.$pub('foo', 1, 2, 3);
};
return {
pubHandler
};
}
};
</script>
全局事件订阅/取消订阅
<template>
<div class="child">
<button @click="unsubHandler">注销事件</button>
</div>
</template>
<script>
import { getCurrentInstance, onMounted } from 'vue';
export default {
setup(props, context) {
const { proxy } = getCurrentInstance();
const watchHandler = ([a, b, c] = args) => {
console.log('组件件监听触发!');
};
onMounted(() => {
proxy.$sub('foo', watchHandler);
});
const unsubHandler = () => {
proxy.$unsub('foo', watchHandler);
};
return {
unsubHandler
};
}
};
</script>
下一章:(十六)Vue3.x中使用vue-router的新特性
上一章:(十四)Vue3.x核心之getCurrentInstance
ps:“嗨,你还是一点都没有变阿!”,对了,他可能没有夸你。