关于vuex:手写vuex

2次阅读

共计 3615 个字符,预计需要花费 10 分钟才能阅读完成。

vuex

vuex 集中式存储管理利用的所有组件的状态, 并以相应的规定保障状态以可预测的形式发生变化

应用 vuex

(1) 导入 vuex

vue add vuex

(2) 外围概念
state: 状态数据
mutations: 批改状态的函数
action: 异步操作

(3) 状态 store — 保留利用状态

export default new Vuex.store({
    state: {counter: 0}
})

(4) mutation — 状态变更

export default new Vuex.store({
    state: {counter: 0},
    mutations: {add(state){state.counter++}
    }
})

(5) getters — 从 state 中派生出的状态, 相似计算属性

export default new Vuex.store({
    state: {counter: 0},
    mutations: {add(state){state.counter++}
    },
    getters: {doubleCounter(state) {return state.counter * 2}
    }
})

(6) actions — 增加业务逻辑

export default new Vuex.store({
    state: {counter: 0},
    mutations: {add(state){state.counter++}
    },
    actions: {add({commit}){setTimeout(()=>{commit('add');
            },1000)
        }
    },
    getters: {doubleCounter(state) {return state.counter * 2}
    }
})

测试代码

 
<p @click="$store.commit('add')">counter: {{$store.state.counter}}</p>
<p @click="$store.dispatch('add')">async counter: {{$store.state.counter}}</p> 
<p>double:{{$store.getters.doubleCounter}}</p>

vuex 原理剖析

任务分析

  1. 实现插件
    (1) 实现 store 类

        维持一个响应式的 store
        实现 commit
        实现 dispatch
        getters

    (2) 挂载 $store

  2. 初始化 Store 申明, install 实现
let Vue;
class Store{constructor(options) {
        // data 响应式解决
        this._vm = new Vue({
            data: {$$state: options.state}
        })
    }
    get state(){return this._vm_data.$$state}
}

function install(_Vue) {
    Vue = _Vue;
    Vue.mixin({beforeCreated(){if (this.$options.store) {Vue.prototype.$store = this.$options.store}
        }
    })
}
export default {Store, install}

实现 commit 依据用户传入的 type 获取并执行对应的 mutations

class Store{constructor(options) {
        // data 响应式解决
        this._vm = new Vue({
            data: {$$state: options.state}
        })
        // 保留用户配置的 mutations 选项
        this._mutations = options._mutations || {};
        this._actions = options._actions || {};}
    get state(){return this._vm_data.$$state}
    commit (type) {
        // 获取 type 指定的 mutation
        const entry = this._mutations[type];
        if (!entry) {console.log('unknow mutation')
            return
        }
        // 传递 state 给 mutation
        entry(this.state);
    }
    dispatch (type) {
        // 获取 type 指定的 mutation
        const entry = this._mutations[type];
        if (!entry) {console.log('unknow mutation')
            return
        }
        // 传递 state 给 mutation
        entry(this.state);
    }
}

实现 dispatch 依据用户传入的 type 获取并执行对应的 actions

class Store{constructor(options) {
        // data 响应式解决
        this._vm = new Vue({
            data: {$$state: options.state}
        })
        // 保留用户配置的 mutations 选项
        this._mutations = options._mutations || {};
        this._actions = options._actions || {};
        // 须要异步解决上下文
        this.dispatch = this.dispatch.bind(this);
    }
    get state(){return this._vm_data.$$state}
    dispatch (type) {
        // 获取 type 指定的 action
        const entry = this._actions[type];
        if (!entry) {console.log('unknow action')
            return
        }
        // 传递 state 给 action
        entry(this);
    }
}

实现 getters

class Store{constructor(options) {
        // data 响应式解决
        this._vm = new Vue({
            data: {$$state: options.state}
        })
        // 保留用户配置的 mutations 选项
        this._mutations = options._mutations || {};
        this._actions = options._actions || {};
        // 须要异步解决上下文
        this.dispatch = this.dispatch.bind(this);
        
        this.getters = {};
        Object.keys(options.getters).forEach(getterName => {
        Object.defineProperty(this.getter, getterName, {get:()=>{return options.getters[getterName](this.state)
            }
        })
       })
    }
    get state(){return this._vm_data.$$state}
}

残缺代码


// 1. 插件: 挂载 $store
// 2. 实现 Store
let Vue
class Store {constructor(options) {
        // data 响应式解决
        this._vm = new Vue({
            data: {$$state: options.state}
        })
        this._mutations = options.mutations;
        this._actions = options.actions;
        this.commit = this.commit.bind(this);
        this.dispatch = this.dispatch.bind(this);

        // 实现 getters
        this.getters = {};
        Object.keys(options.getters).forEach(getterName => {
            Object.defineProperty(this.getters, getterName, {get: () => {return options.getters[getterName](this.state)
                }
            })
        })
    }
    get state(){return this._vm._data.$$state}
    commit(type, payload) {const entry = this._mutations[type];
        if (!type) {console.log('unknow muyations type')
        }
        entry(this.state, payload)
    }

    dispatch(type, payload) {const entry = this._actions[type];
        if (!type) {console.log('unknow action type')
        }
        entry(this, payload)
    }

}

function install (_Vue) {
    Vue = _Vue;
    Vue.mixin({beforeCreate() {if (this.$options.store) {Vue.prototype.$store = this.$options.store;}
        },
    })
}
export default {Store, install};
正文完
 0