[路飞] vuex 插件原理初探

148 阅读1分钟

1. state属性

$store.state属性就是_vm.data的$$state属性

class Store{
    constructor(options){
        this._mutations = options.mutations
        this._actions = options.actions
        this._vm = new Vue({
            data: {
                $$state:options.state// Vuex的state是Vue实例的$$state
            }
        })



        this.commit = this.commit.bind(this)
        this.dispatch = this.dispatch.bind(this)

       
    }
  

    get state(){
        return this._vm.$data.$$state// 封装
    }
}

2. commit方法

调用commit,执行mutation函数。mutation函数实质是对_vm.$$state做修改,包括新增减少属性、修改属性。

commit(type,payload){
    this._mutations[type](this.state,payload)
}

3. dispatch方法

调用dispatch,执行actions函数。实质上,actions函数的架构位置是在组件层和store层之间。

// this = store
dispatch(type,payload){
    this._actions[type](this,payload)// @@@ store中的方法经过bind后,直接给actions函数
    
}

4. getters属性

修改Store构造函数,增加关于getters的实现逻辑。具体实现方式是使用store的options.getters的定义生成vm的options.computed的定义。组件读取$store.getters时,$store.getters作为_vm计算属性的代理:

class Store{
    constructor(options){
        this._mutations = options.mutations
        this._actions = options.actions
        this._getters = options.getters
        
        this.getters = {}
        
        // 使用store的options.getters定义生成vm的options.computed定义
        const computed = {}
        Object.keys(this._getters).forEach(getterName=>{
            computed[getterName] = ()=>{ 
                return this._getters[getterName](this.state)
            }
            
            // 组件读取$store.getters时,$store.getters作为_vm计算属性的代理
            Object.defineProperty(this.getters,getterName,{
                get:()=>{
                    return this._vm[getterName]// 访问getters,其实是访问computed
                }
            })
        })

        this._vm = new Vue({
            data: {
                $$state:options.state
            },
            computed // @@@
        })



        this.commit = this.commit.bind(this)
        this.dispatch = this.dispatch.bind(this)

       
    }
  

    get state(){
        return this._vm.$data.$$state
    }

    set state(_){
        console.error('use replace state') 
    }

    commit(type,payload){ 
        this._mutations[type](this.state,payload)
    }

    dispatch(type,payload){
        this._actions[type](this,payload) 
        
    }
    
}