关于vuex:手写vuex

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};

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理