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

lolo
12 声望0 粉丝

引用和评论

0 条评论