本章我們將聊到一個(gè)重點(diǎn),在Vue3.x中實(shí)現(xiàn)全局通訊。
1、前言:由于Vue3.x中刪除了off,因此不能借助于一個(gè)單獨(dú)的Vue實(shí)例來實(shí)現(xiàn)全局事件的發(fā)布和訂閱與取消訂閱(也就是跨組件通訊)。
2、概述:mitt是一個(gè)三方庫,npm安裝:npm install -D mitt
3、使用:我們以同樣使用插件的方式將mitt集成到Vue中。
4、mitt對象:
- all(Map對象):包含了所有訂閱的事件名稱,及對應(yīng)的處理方法數(shù)組。
- emit(方法):觸發(fā)事件,參數(shù)為(事件名(方法名),攜帶的參數(shù)),當(dāng)- 前攜帶的參數(shù)只能為一個(gè),不能為多個(gè)。
- on(方法):創(chuàng)建事件訂閱,參數(shù)為(事件名,處理方法)。
- off(方法):取消事件訂閱,參數(shù)為(事件名,處理方法)。
5、全局事件總成搭建:
import _ from 'lodash';
import mitt from 'mitt';
export default {
install(Vue, options) {
const _emitter = mitt();
// 全局發(fā)布(在Vue全局方法中自定義$pub發(fā)布方法)
// 這里做了$pub方法能夠攜帶多個(gè)參數(shù)的處理,方便我們再業(yè)務(wù)中觸發(fā)事件時(shí)帶多個(gè)參數(shù)
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、組件實(shí)例中使用:
全局事件發(fā)布
<template>
<div class="child">
<button @click="pubHandler">發(fā)起事件</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('組件件監(jiān)聽觸發(fā)!');
};
onMounted(() => {
proxy.$sub('foo', watchHandler);
});
const unsubHandler = () => {
proxy.$unsub('foo', watchHandler);
};
return {
unsubHandler
};
}
};
</script>
下一章:(十六)Vue3.x中使用vue-router的新特性
上一章:(十四)Vue3.x核心之getCurrentInstance
ps:“嗨,你還是一點(diǎn)都沒有變阿!”,對了,他可能沒有夸你。