let Vue
// 1.创建Store类
class Store {
constructor(options) {
// 8.存储mutations属性
this._mutations = options.mutations || {};
// 11.存储action属性
this._actions = options.actions || {}
// 18.存储getters属性
this._getters = options.getters || {}
let computed = {};
// 17.使用方法是$store.getters.***,所以定义一个getters属性
this.getters = {}
const store = this;
// 18.循环getters属性的key
Object.keys(this._getters).forEach(key => {
// 19.获取用户定义的getters
const fn = store._getters[key];
// 20.转换为computed可以使用的无参数形式,创建同名函数
computed[key] = function () {
return fn(store.state)
};
// 21.因为在computed创建了指定的计算函数,相当于再this._vm下就可访问到计算属性
// 同理,外界使用$store.getters.***获取时,先从this.getters匹配指定属性,读取属性时执行get函数,最终从this._vm上找去计算属性,实则是this._vm.***
Object.defineProperty(store.getters, key, {
get: () => store._vm[key]
})
})
// 4.响应式state属性
this._vm = new Vue({
data: {
$$state: options.state
// 区别是 如果不使用$$,在_vm根上会有state属性;如果使用$$在_vm根上会有_data属性挂载这响应式$$state
},
// 16.创建计算属性getters方法
computed
});
// 15.避免印在setTimeout等 this指向问题,重新设置this
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
}
// 5.获取state属性值
get state() {
return this._vm._data.$$state
}
// 6.如果想修改state报错提示
set state(v) {
console.error('please No!');
}
// 7.定义commit 使用方式commit(type,payload)
commit(type, payload) {
// 9.根据type从this._mutations获取需要执行的方法
let entry = this._mutations[type];
if (!entry) {
console.error('entry no!');
}
// 10.传递state
entry(this.state, payload)
}
// 12.dispatch传递的是store类,所以直接传递this
dispatch(type, payload) {
// 13.根据type从this._mutations获取需要执行的方法
let entry = this._actions[type];
if (!entry) {
console.error('entry no!');
}
// 14.传递this
entry(this, payload)
}
}
// 2.创建install插件,形参_Vue就是Vue的构造函数
function install(_Vue) {
Vue = _Vue
// 3.挂载$store到Vue,使用混入延迟到构造完成后执行
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
}
}
})
}
export default {
Store,
install
}
网友评论