美文网首页
实现一个vuex-loading插件 (借鉴版)

实现一个vuex-loading插件 (借鉴版)

作者: Cooliean | 来源:发表于2020-03-01 11:06 被阅读0次

借鉴1 https://www.ahwgs.cn/vuex-loading-plugin.html
借鉴2https://www.jianshu.com/p/82b34a22f3af

这个版本问题如下:

  • 使用了 子模块,但是实现代码哪里没有用子模块的方法调用,导致程序不能运行
        // 原来调用方式
        store.commit({
            type: `${HIDE}`,
            payload: action.type
        });
        
        
        // 可以修改成
        store.commit({
            type: `${namespace}/${HIDE}`,
            payload: action.type
        });
        
        // 或者
        namespaced: false,
        
    
  • global 多个action运行时,只要有一个执行完毕就true,这样不合理
  • mutations 定义出错,具体看下面代码了(懒癌范了)

完整代码如下

/**
 * vuex 仿 dva-loading
 * 注意测试action不能直接用setTimeout,要返回一个带Promise的timeout才可以
 * @type {string}
 */

const NAMESPACE = "loading"; // 定义模块名
const SHOW = "@@LOADING/SHOW" // 显示mutation 同步type
const HIDE = "@@LOADING/HIDE"


const createLoadingPlugin = ({
    namespace = NAMESPACE,
    includes = [],
    excludes = []
} = {}) => {
    return store => {
        if (store.state[namespace]) {
            throw new Error(
                `createLoadingPlugin: ${namespace} exited in current store`
            );
        }


        // new vuex的时候注册一个模块进去
        store.registerModule(namespace, {
            namespaced: false,
            state: {
                global: false, // 定义全局loading
                effects: {}
            },
            // 同步方法
            mutations: {
                [SHOW](state, {
                    payload
                }) {
                    state.global = true;
                    state.effects = {
                        ...state.effects,
                        [payload]: true // 将当前的action 置为true
                    };

                    console.log('==SHOW==================');
                    console.log('state\n');
                    console.log(JSON.stringify(state, null, '\t'));
                    console.log('========================');
                },
                [HIDE](state, {
                    payload
                }) {
                    state.effects = {
                        ...state.effects,
                        [payload]: false // 将当前的action 置为false
                    };
                    // 遍历所有的model 将所有命名空间中的都置为false
                    const global = Object.keys(state.effects).some(effectKey => {
                        return state.effects[effectKey];
                    });
                    state.global = global;
                    console.log('==HIDE==================');
                    console.log('state\n');
                    console.log(JSON.stringify(state, null, '\t'));
                    console.log('========================');
                }
            }
        });


        store.subscribeAction({
            // 发起一个action 之前会走这里
            before: (action, state) => {
                console.log(`before action ${action.type}`);
                if (onEffect(action, includes, excludes)) {
                    store.commit({
                        type: `${SHOW}`,
                        payload: action.type
                    });
                }
            },
            // 发起一个action 之后会走这里
            after: (action, state) => {
                console.log(`after action ${action.type}`);
                if (onEffect(action, includes, excludes)) {
                    store.commit({
                        type: `${HIDE}`,
                        payload: action.type
                    });
                }
            }
        });
    };
};

// 判断是否要执行
function onEffect({
    type
}, includes, excludes) {
    if (includes.length === 0 && excludes.length === 0) {
        return true;
    }

    if (includes.length > 0) {
        return includes.indexOf(type) > -1;
    }

    return excludes.length > 0 && excludes.indexOf(type) === -1;
}

export default createLoadingPlugin;

相关文章

网友评论

      本文标题:实现一个vuex-loading插件 (借鉴版)

      本文链接:https://www.haomeiwen.com/subject/yimxkhtx.html