vuex使用原理

428 阅读2分钟

4bc04dd8b5fd377815ce3919ac1eea9.png

首先在这个store文件夹里如图把vuex的引用从vue的插件改为本地文件形式

第二步在store文件夹下创建vue.js文件,也就是按照上图的"./vuex"的路径创建文件夹,我们的vuex实现就在这个文件夹里

在写源码之前先来了解一下vuex的使用,以便于思考源码的编写思路 其中store文件下的index文件需要配置参数state,mutations,getters和actions如下图所示

5b805aa39feb6433b960a01299b4122.png

下图为在page文件中的使用,其中async按钮为actiosn的使用,actions是异步方法,加1减1按钮为mutations同步操作

2bc7648d5bd2abbad9cf8ff38c80c27.png async和加1减1的具体事件如下图

dc934489f58d0108082651e3140f5d7.png 此代码运行结果如图

5d2c999bfd53b21fbb87225c93b7136.png

这里点击加1按钮,state和getters的值会立即加1,点击减1按钮state和getters的值会立即减1,而点击 async后会在1秒钟之后执行加1操作

了解了以上vuex的使用方法后直接上vuex模拟实现代码

let Vue;

class Store {
    constructor(options) {
        this.vm = new Vue({
            data: {
                state: options.state
            }
        })
        //Store的vm把store里的state放在Vue的data中,就可以双向数据绑定了
        let getters = options.getters || {}
        this.getters = {}
        Object.keys(getters).forEach(getterName => {
            Object.defineProperty(this.getters, getterName, {
                get: () => {
                    return getters[getterName](this.state);
                }
            })
        })
        let mutations = options.mutations || {}
        this.mutations = {}
        Object.keys(mutations).forEach(mutationName => {
            this.mutations[mutationName] = payload => {
                mutations[mutationName](this.state, payload)
            }
        })
        let actions = options.actions || {}
        this.actions = {}
        Object.keys(actions).forEach(actionName => {
            this.actions[actionName] = payload => {
                actions[actionName](this, payload)
            }
        })
    }
    dispatch(method, payload) {
        this.actions[method](payload)
    }
    commit = (method, payload) => {
    //注意这里的commit要使用箭头函数,因为在调用dispatch的时候走到这个commit方法的时候this指向为undefined,改为箭头函数this指向为Vue
        this.mutations[method](payload);
    }
    get state() {
        return this.vm.state
    }
}

const install = (v) => {
    Vue = v;
    Vue.mixin({  //mixin混入方法需要学习了解,这里混入的目的是给全局的Vue类加上$store
        beforeCreate() {
            if (this.$options && this.$options.store) {
            //注意一定要熟练掌握this指向问题,这里this指向Vue
                this.$store = this.$options.store;
            } else {
                this.$store = this.$parent && this.$parent.$store;
            }
        }
    })
}

export default {
    install, Store //将install方法和Store类导出
}

vuex中还有module这个属性,可以继续深入了解一下它的使用或者实现原理