前言
在项目中,如何管理loading
是一个很头疼的方式,有的是在请求封装里去做了一个全屏loading
,有的是在单页面中管理一个loading
,比如如下:
data(){
return{
loading:false
}
},
methods:{
async change(){
this.loading = true
// 执行异步操作
await asyncAction()
this.loading = false
}
}
如果管理的是一个还好,但是如果页面上存在着多个异步操作,维护起来简直要命。
之前有使用过dva
这个基于react-saga
的数据流框架,他有一个插件dva-loading
非常的好用,但由于是React
框架上的。一直想着如何借鉴其思路实现一个基于vuex
的loading
插件,是非常想做的一件事。
好在,vuex@3.1.0
中新增了一个subscribeAction
这个方法。
store.subscribeAction({
before: (action, state) => {
console.log(`before action ${
action.type}`)
},
after: (action, state) => {
console.log(`after action ${
action.type}`)
}
})
简单来说就是我们在发起的每一个action
都可以在这个方法中订阅到,before
和after
两个过程。心里一想,这岂不是跟dva-loading
有一样的一个动作吗。
如何实现
先看一下dva-loading
的源码,分析一下:
为了方便描述,直接贴源码补充注释,具体dva
的使用与vuex
的异同,可以看我之前写的那篇如何使用dva与服务端进行数据交互
const SHOW = '@@DVA_LOADING/SHOW'; // 定义reducer 类似于mutation
const HIDE = '@@DVA_LOADING/HIDE';
const NAMESPACE = 'loading'; // 定义命名空间
function createLoading(opts = {
}) {
// 获取参数中的命名空间或者本地的名称
const namespace = opts.namespace || NAMESPACE;
const {
only = [], except = [] } = opts;
if (only.length > 0 && except.length > 0) {
throw Error('It is ambiguous to configurate `only` and `except` items at the same time.');
}
// 初始化state
const initialState = {
global: false, // 定义全局 loading
models: {
}, // 定义