当前有个需求,是路由内部某个组件发生某些操作时,开启/关闭全局(整个页面)的loading效果。
1. 需求分析
在收到这个需求时,考虑到关键点在于跨组件通信,于是想到以下这些方法并进行分析可行性:
序号 | 方法 | 适用场景 | 是否可行 | 备注 |
---|---|---|---|---|
1 | props、$emit | V2、V3,直接父子组件 | 否 | |
2 | Event Bus | V2、V3,跨组件 | 是 | EventBus.$ emit发送消息,EventBus.$ on监听接收消息 |
3 | Vuex | V2,跨组件 | 是 | 手动监听vuex变化 |
4 | provide、inject | V2、V3, 跨组件 | 是 | |
5 | slots | V2、V3,直接父子组件 | 否 | |
6 | Ref / Reactive | V3,直接父子组件 | 否 | |
7 | useAttrs | V3,直接父子组件 | 否 | |
8 | Pinia | V3,跨组件 | 是 | 手动监听pinia变化 |
通过以上分析,认为provide/inject的方式比较方便快捷(更熟悉),于是通过此方式实现。
2. 实现
(1)app.vue
全局loading状态、方法控制
<template>
<div id="app" v-loading="globalLoading">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
provide(){
return {
hideGLoading: this.hideGLoading, // 全局loading关闭方法
showGLoading: this.showGLoading, // 全局loading显示方法
}
},
data(){
return{
globalLoading: false, // 全局loading状态
}
},
methods:{
hideGLoading() {
this.globalLoading = false;
},
showGLoading() {
this.globalLoading = true;
}
}
}
</script>
(2)局部组件
handleGather 时触发全局loading显示,接口请求完触发全局loading关闭。
inject: ['hideGLoading','showGLoading'], // 全局loading
/** methods 操作 */
handleGather(row) {
this.showGLoading();
getAPIData().then(res => {
// this.gatherInfo = res.data; 接口数据操作
}).finally(() => {
this.hideGLoading();
})
}