手写实现vuex插件的基本功能

实现vuex插件的基本功能(state、commit、dispatch、getters)

  1. vuex的用法
import Vue from 'vue';
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
    state: {
        counter: 1
    },
    mutations: {
        add(state) {
            return state.counter++
        }
    },
    actions: {
        addSync({ commit }, proload) {
            setTimeout(() => {
                commit('add', proload)
            }, 1000)
        }
    },
    getters: {
        doubleCounter(state) {
            return state.counter * 2
        },
        mutilCounter(state) {
            return state.counter * state.counter
        }
    },
    modules: {
    }
})

  1. 需求分析
  1.实现Store类中的响应式state,commit,dispath,响应式getters
  
  2.实现Store的安装,定义install方法,使用vue.use()方式安装
  
  3.不考虑实现modules模板
  
 1. Store
	 保存选项:mutations, _actions,getters
	 响应式状态:new Vue({data: {$$state: options.state}})
	 Get state()/set state()
	 Commit(): entry => entry(this.state)
	 dispatch(): entry => entry(this)
2. Install
	 Vue.prototype.$store
  1. 显示install方法,利用Vue.mixin()全局混入,在全局混入created生命周期,在new Vue({})创建的时候,通过this. o p t i o n s . s t o r e 拿 到 实 例 中 的 s t o r e , 将 s t o r e 挂 载 到 全 局 V u e 实 例 中 , 利 用 t h i s . options.store拿到实例中的store,将store挂载到全局Vue实例中,利用this. options.storestorestoreVuethis.store访问store的属性。
const install = (_Vue) => {
    Vue = _Vue
    Vue.mixin({
        created() {
            if (this.$options.store) {
                Vue.prototype.$store = this.$options.store
            }
        },
    })
}
  1. 创建Store类,继承new Vuex.Store()实例的属性对象集合
class Store {
    constructor(options) {
        const state = options.state
        this.mutations = options.mutations
        this.actions = options.actions
        this.getters = options.getters
        }
  }

将state定义 为 vue响应式 数据 ,可以使用new Vue()实例定义响应式数据,或者利用 Vue.util.defineReactive(this, “state”, state)定义响应式state.

     this._vm = new Vue({
            data() {
                return {
                    $$state: state
                }
            },
        })
     利用es6中的getset方法获取响应式state
     get state() {
        return this._vm._data.$$state
    }
    set state(v) {
        console.log('please use replaceState to reset state!');

    }

实现commit和dispatch方法

 //commit触发muations
    commit = (type, proload) => {
        const fun = this.mutations[type]
        // console.log(type, fun, 'fun');
        if (fun) {
            fun(this.state, proload)
        } else {
            console.log('commit方法未定义')
        }
    }
    //commit触发actions
    dispatch = (type, proload) => {
        const fun = this.actions[type]
        if (fun) {
            fun(this, proload)
        } else {
            console.log('actions方法未定义')
        }
    }
    注意:最好是利用箭头函数,否则会存在this指向问题
    可以定义普通函数,利用bind绑定函数this的上下文

实现响应式getters
利用上面创建的new Vue({})实例,将getters方法映射成vue computed属性的方法,挂载computed计算属性

Object.keys(this.getters).forEach(v => {
            computed[v] = this.getters[v]
            const vm = this._vm
            Object.defineProperty(this.getters, v, {
                get() {
                    return vm.$options.computed[v](vm._data.$$state)
                }
            })
        })

导出Store和install

export default { install, Store }

4.效果图
手写实现vuex插件的基本功能_第1张图片

5.kVuex整体代码

/* eslint-disable no-unused-vars */
let Vue
class Store {
    constructor(options) {
        const state = options.state
        this.mutations = options.mutations
        this.actions = options.actions
        this.getters = options.getters
        const computed = {}
        //state响应式的
        // Vue.util.defineReactive(this, "state", state)
        //初始化Vue实例,监测state为响应式数据
        this._vm = new Vue({
            data() {
                return {
                    $$state: state
                }
            },
            computed
        })
        Object.keys(this.getters).forEach(v => {
            computed[v] = this.getters[v]
            const vm = this._vm
            Object.defineProperty(this.getters, v, {
                get() {
                    return vm.$options.computed[v](vm._data.$$state)
                }
            })
        })
    }
    get state() {
        return this._vm._data.$$state
    }
    set state(v) {
        console.log('please use replaceState to reset state!');

    }
    //commit触发muations
    commit = (type, proload) => {
        const fun = this.mutations[type]
        // console.log(type, fun, 'fun');
        if (fun) {
            fun(this.state, proload)
        } else {
            console.log('commit方法未定义')
        }
    }
    //commit触发actions
    dispatch = (type, proload) => {
        const fun = this.actions[type]
        if (fun) {
            fun(this, proload)
        } else {
            console.log('actions方法未定义')
        }
    }
}
const install = (_Vue) => {
    Vue = _Vue
    Vue.mixin({
        beforeCreate() {
            if (this.$options.store) {
                Vue.prototype.$store = this.$options.store
                // console.log(this.$options.store, 'store');
            }
        },
    })
}
export default { install, Store }

你可能感兴趣的:(前端架构师成长之路,vue,js,面向对象编程,源码)