由于时间问题,暂时先把代码完整的贴上来,感兴趣的朋友可以自行研究或收藏。等我那时有时间的时候,对专栏文章进行排序,并逐一讲解代码
一、对外暴露的入口文件index.js
import Vue from "vue";
import Vuex from "./kvuex";Vue.use(Vuex);export default new Vuex.Store({state: {count: 1},mutations: {add(state) {state.count++;}},actions: {add({commit}) {setInterval(() => {commit("add");}, 1000)}},getters: {doubleCounter: state => {return state.count * 2;}}
})
二、状态管理器处理实例
let Vue;class Store {constructor(options) {// 1.获取选项内容const { state, getters, mutations, actions, modules } = options;// 2.保存选项this._actions = actions || {};this._mutations = mutations || {};// 3.动态设置getter属性this.getters = {}const computed = {}Object.entries(getters).forEach(([key, fn]) => {computed[key] = () => {return fn(this.state, this.getters);};Object.defineProperty(this.getters, key, {get: () => this._vm[key]})});// 4.做响应式状态state属性this._vm = new Vue({data: {// $$的变量不会走依赖收集的过程$$state: options.state},computed});// 5.上下文绑定 - 指定commit, dispatch 函数的执行环境this.commit = this.commit.bind(this);this.dispatch = this.dispatch.bind(this);}// 暴露属性的访问接口get state() {return this._vm._data.$$state;}// 注意:Setter函数中必须要有一个参数,即使用不到set state(v) {console.error("please use replaeState to reset state");}commit(type, payload) {// 获取mutationsif (!this._mutations[type]) {console.error("unknown mutation type");}// data都挂载在实例的 _data 属性上。直接拿不到。 在模板中能直接拿到this._mutations[type](this.state, payload);}// 发起函数执行的方法dispatch(type, payload) {// 获取actionsif (!this._actions[type]) {console.error("unknown actions type");}this._actions[type](this, payload);}
}function install(_Vue) {Vue = _Vue;// 挂载storeVue.mixin({beforeCreate() {if (this.$options.store) {Vue.prototype.$store = this.$options.store;}}});
}export default { Store, install }