VUEX的底层实现

1,050 阅读1分钟
(function (global, factory) {
    global.Vuex = factory();
})(this, function () {
    let Vue;
    class Store {
        constructor(options) {
            //Vue 代表的就是全局的Vue
            let vm = new Vue({
                data: {
                    state: options.state || {}
                }
            })
            // this.state = options.state || []
            this.state = vm.state
            this.mutations = {};
            let mutations = options.mutations || {};
            Object.keys(mutations).forEach(key => {
                this.mutations[key] = (option) => {
                    mutations[key].call(this, this.state, option)
                }
            });



            this.actions = {};
            let actions = options.actions || {};
            Object.keys(actions).forEach(key => {
                this.actions[key] = (option) => {
                    //this 就是store
                    //第一个this 就是把函数中的this改成store
                    //第二个this 就是传给函数的实参  store
                    actions[key].call(this, this, option)
                }
            });


            this.getters = {};
            let getters = options.getters || {};
            Object.keys(getters).forEach(key => {
                Object.defineProperty(this.getters, key, {
                    get: () => {
                        return getters[key].call(this, this.state)
                    }
                })//监听对象中的属性
            });
            let commit = this, commit;
            this.commit = (type, option) => {
                commit.call(this, type, option)
            };
            let dispatch = this.dispatch;
            this.dispatch = (type, option) => {
                dispatch.call(this, type, option)
            };
        }
        commit(type, option) {
            this.mutations[type](option);
            // console.log(this.mutations,type);
        }
        dispatch(type, option) {
            this.actions[type](option);
        }

    }
    function install(_Vue) {
        Vue = _Vue;
        console.log(666, _Vue);
        //给当前项目的每一个组件都混入了一个beforecreate的钩子函数  若组件某个组件存在对应的钩子函数那么先执行混入的钩子函数
        _Vue.mixin({
            beforeCreate() {
                //this 指的就是当前那个组件
                console.log('beforecreate', this);
                if (this.$options && this.$options.store) {
                    //证明该组件是跟组件
                    //把对应的store放到了自身的$store身上
                    this.$store = this.$options.store;
                    console.log(111);
                } else {
                    //走到这里的this  都是其他后代组件
                    this.$store = (this.$parent && this.$parent.$store)
                }
            },
        })

    }
    function mapState(ary) {
        let obj = {

        };
        ary.forEach(key => {
            obj[key] = function () {
                //this是当前实例
                return this.$store.state[key]
            }
        })
        return obj
    }
    function mapGetters(ary) {
        let obj = {

        };
        ary.forEach(key => {
            obj[key] = function () {
                //this是当前实例
                return this.$store.getters[key]
            }
        })
        return obj
    }
    function mapActions(ary) {
        let obj = {};
        ary.forEach(key => {
            obj[key] = function (option) {
                this.$store.dispatch(key, option)
            }
        })
        return obj
    }
    function mapMutations(ary) {
        let obj = {};
        ary.forEach(key => {
            obj[key] = function (option) {
                this.$store.commit(key, option)
            }
        })
        return obj
    }
    return {
        Store,
        install,
        mapState,
        mapGetters,
        mapActions,
        mapMutations
    }
})