Step01.命名一个storeService要一个只读state
var storeService = new Object({
    _state: { age: 1 },
    get state() {
        return this._state;
    },
    set state(v) {
        throw new Error(' is read only.')
    }
});
Step02.创建一些列mutation改变state
var storeService = new Object({
    _state: { age: 1 },
    get state() {
        return this._state;
    },
    set state(v) {
        throw new Error(' is read only.')
    },
    mutationModifyAge(newAge) {
        state.age = newAge;
    },
    mutationModifyAge2(newAge) {
        state.age = newAge;
    },
    mutationModifyAge3(newAge) {
        state.age = newAge;
    }
});
Step03.需要一个watch监听改变,每一次改变状态的时候(执行mutation)调用listenCallback 返回状态
var storeService = new Object({
    _listeners: [],
    _state: { age: 1 },
    get state() {
        return this._state;
    },
    set state(v) {
        throw new Error(' is read only.')
    },
    mutationModifyAge(newAge) {
        state.age = newAge;
        this._dealCallback();
    },
    mutationModifyAge2(newAge) {
        state.age = newAge;
        this._dealCallback();
    },
    mutationModifyAge3(newAge) {
        state.age = newAge;
        this._dealCallback();
    },
    _dealCallback() {
        this._listeners.forEach(listener => listener(this.state))

    },
    watch(listener) {
        // 优化想要第一次监听的时候返回当前状态
        listener(this.state);
        this._listeners.push(listener);
    }
});
// 监听store
storeService.watch(function (state) {
    console.log('callback', state);
})
// 改变状态
storeService.mutationModifyAge(2)
Step04.统一使用dispatch调用mutation法
var storeService = new Object({
    _listeners: [],
    _state: { age: 1 },
    get state() {
        return this._state;
    },
    set state(v) {
        throw new Error(' is read only.')
    },
    dispatch(type, ...paylod) {
        // 打印日志信息
        console.log(type ? type : '监听', '改变之前的状态', this.state);
        if (this._mutation[type]) {
            this._mutation[type](this.state, ...paylod);
        }
        console.log(type ? type : '监听', '改变之后的状态', this.state);
        // 可以少写好多个listenCallback
        this._dealCallback();
    },
    _mutation: {
        mutationModifyAge(state, newAge) {
            state.age = newAge;
        },
        mutationModifyAge2(state, newAge) {
            state.age = newAge;
        },
        mutationModifyAge3(state, newAge) {
            state.age = newAge;
        }
    },
    _dealCallback() {
        this._listeners.forEach(listener => listener(this.state))

    },
    watch(listener) {
        // 优化想要第一次监听的时候返回当前状态
        // listener(this.state);
        // 优化让第一次监听也可以记录历史日志
        this.dispatch();
        this._listeners.push(listener);
    }
});
// 监听store
storeService.watch(function (state) {
    console.log('callback', state);
})
// 改变状态
storeService.dispatch('mutationModifyAge', 2)
以上内容为创建一个简单的store。
以下开始按照Vuex0.3.0开始优化
Step05.vuex dispatcher调用的方法是mutation,
mutation是唯一操作state的方法,
mutation不可包含任何副作用,
mutation对外暴露dispatch调用将上面的mutation 改为mutation
var storeService = new Object({
    _listeners: [],
    _state: { age: 1 },
    get state() {
        return this._state;
    },
    set state(v) {
        throw new Error(' is read only.')
    },
    dispatch(type, ...paylod) {
        // 打印日志信息
        console.log(type ? type : '监听', '改变之前的状态', this.state);
        if (this._mutation[type]) {
            this._mutation[type](this.state, ...paylod);
        }
        console.log(type ? type : '监听', '改变之后的状态', this.state);
        // 可以少写好多个listenCallback
        this._dealCallback();
    },
    _mutation: {
        mutationModifyAge(state, newAge) {
            state.age = newAge;
        },
        mutationModifyAge2(state, newAge) {
            state.age = newAge;
        },
        mutationModifyAge3(state, newAge) {
            state.age = newAge;
        }
    },
    _dealCallback() {
        this._listeners.forEach(listener => listener(this.state))

    },
    watch(listener) {
        // 优化想要第一次监听的时候返回当前状态
        // listener(this.state);
        // 优化让第一次监听也可以记录历史日志
        this.dispatch();
        this._listeners.push(listener);
    }
});
// 监听store
storeService.watch(function (state) {
    console.log('callback', state);
})
// 改变状态
storeService.dispatch('mutationModifyAge', 2)
Step05.vuex中mutation为纯函数,不可包含任何副作用,添加action来处理一系列副作用,最终还是调用dispatch 去改变state
var storeService = new Object({
    _listeners: [],
    _state: { age: 1 },
    get state() {
        return this._state;
    },
    set state(v) {
        throw new Error(' is read only.')
    },

    dispatch(type, ...paylod) {
        // 打印日志信息
        console.log(type ? type : '监听', '改变之前的状态', this.state);
        if (this._mutation[type]) {
            this._mutation[type](this.state, ...paylod);
        }
        console.log(type ? type : '监听', '改变之后的状态', this.state);
        // 可以少写好多个listenCallback
        this._dealCallback();
    },
    _mutation: {
        mutationModifyAge(state, newAge) {
            state.age = newAge;
        },
        mutationModifyAge2(state, newAge) {
            state.age = newAge;
        },
        mutationModifyAge3(state, newAge) {
            state.age = newAge;
        }
    },
    _dealCallback() {
        this._listeners.forEach(listener => listener(this.state))
    },
    watch(listener) {
        // 优化想要第一次监听的时候返回当前状态
        // listener(this.state);
        // 优化让第一次监听也可以记录历史日志
        this.dispatch();
        this._listeners.push(listener);
    },
    bindAction(actions) {
        this.actions = Object.create(null);
        this._actions = Object.create(null);

        function createAction(action, store) {
            if (typeof action === 'function') {
                return (...payload) => action(store, ...payload)
            }
        }
        Object.keys(actions).forEach(name => {
            console.log(actions[name]);
            this._actions[name] = createAction(actions[name], this)
            if (!this.actions[name]) {
                this.actions[name] = (...args) => this._actions[name](...args)
            }
        })
    }
});
var actions = {
    // 包含副作用的action
    asyncModifyAge(store, ...paylod) {
        setTimeout(() => {
            store.dispatch('mutationModifyAge', ...paylod)
        }, 2000);
    },
    // 多次调用dispatch
    asyncMulModifyAge(store, ...paylod) {
        setTimeout(() => {
            store.dispatch('mutationModifyAge', ...paylod)
        }, 2000);
        store.dispatch('mutationModifyAge2', ...paylod)
    }
}
storeService.bindAction(actions);
// 监听store
storeService.watch(function (state) {
    console.log('callback', state);
})
// 改变状态
storeService.dispatch('mutationModifyAge', 2)
storeService.actions.asyncMulModifyAge(21);
Step06 封装成一个类hKeeper
var defaultOption = {
    state: {},
    actions: {},
    mutations: {}
};
class hKeeper {
    constructor(options) {
        options = Object.assign({}, defaultOption, options);
        this._state =  options.state;
        this.listeners = [];
        const dispatch = this.dispatch;
        this.dispatch = (...args) => {
            dispatch.apply(this, args);
        };
        this.actions = Object.create(null);
        this._setupMutations(options.mutations);
        this._setupActions(options.actions);
    }
    get state() {
        return this._state
    }

    set state(v) {
        throw new Error('[hKeeper] hKeeper state is read only.')
    }
    dispatch(type, ...payload) {
        const mutation = this._mutations[type]
        const state = this.state
        if (mutation) {
            mutation(state, ...payload)
        }
        this.listeners.forEach(listener => listener(this.state))
    }
    _setupMutations(mutations) {
        this._mutations = mutations;
    }
    // 设置action
    _setupActions(actions) {
        function createAction(action, store) {
            if (typeof action === 'function') {
                return (...payload) => action(store, ...payload)
            }
        }
        this._actions = Object.create(null)
        Object.keys(actions).forEach(name => {
            this._actions[name] = createAction(actions[name], this)
            if (!this.actions[name]) {
                this.actions[name] = (...args) => this._actions[name](...args)
            }
        })
    }
    watch(listener) {
        listener(this.state);
        this.listeners.push(listener)
    }
}
var storeService = new hKeeper(
    {
        state: { age: 1 },
        actions: {
            // 包含副作用的action
            asyncModifyAge(store, ...paylod) {
                setTimeout(() => {
                    store.dispatch('mutationModifyAge', ...paylod)
                }, 2000);
            },
            // 多次调用dispatch
            asyncMulModifyAge(store, ...paylod) {
                setTimeout(() => {
                    store.dispatch('mutationModifyAge', ...paylod)
                }, 2000);
                store.dispatch('mutationModifyAge2', ...paylod)
            }
        },
        mutations: {
            mutationModifyAge(state, newAge) {
                state.age = newAge;
            },
            mutationModifyAge2(state, newAge) {
                state.age = newAge;
            },
            mutationModifyAge3(state, newAge) {
                state.age = newAge;
            }
        }
    }
)
// 监听store
storeService.watch(function (state) {
    console.log('callback', state);
})
// 改变状态
storeService.dispatch('mutationModifyAge', 2)
storeService.actions.asyncMulModifyAge(21);
参考Vuex0.3.0版本 applyMiddleware 参考Redux
https://github.com/HereSincer...

here
34 声望0 粉丝