由于时间问题,暂时先把代码完整的贴上来,感兴趣的朋友可以自行研究或收藏。等我那时有时间的时候,对专栏文章进行排序,并逐一讲解代码
一、对外暴露的入口文件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) {
// 获取mutations
if (!this._mutations[type]) {
console.error("unknown mutation type");
}
// data都挂载在实例的 _data 属性上。直接拿不到。 在模板中能直接拿到
this._mutations[type](this.state, payload);
}
// 发起函数执行的方法
dispatch(type, payload) {
// 获取actions
if (!this._actions[type]) {
console.error("unknown actions type");
}
this._actions[type](this, payload);
}
}
function install(_Vue) {
Vue = _Vue;
// 挂载store
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store;
}
}
});
}
export default { Store, install }