let Vue
class Store {
constructor(optoins) {
this._mutations = optoins.mutations
this.actions = optoins.actions
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
this.wrapperGetters = optoins.getters;
const computed = {}
this.getters = {}
const store = this
Object.keys(this.wrapperGetters).forEach((key) => {
const fn = this.wrapperGetters[key];
//vue实例computed没有参数,但是getters中的函数是有参数的,默认传入state,所以做一层包裹处理
computed[key] = function() {
return fn(store.state)
}
Object.defineProperty(store.getters, key, {
get() {
return store._vm[key]
},
})
})
//借vue实现store中数据的响应式
this._vm = new Vue({
data: {
state: optoins.state,
},
computed,
})
}
get state() {
return this._vm.state
}
//设置state不能修改
set state(val) {
console.error('no allowed to modify state')
}
commit(type, payload) {
const entry = this._mutations[type]
if (!entry) {
return console.error('unknow mutations type:' + type)
}
entry(this.state, payload)
}
dispatch(type, payload) {
let entry = this.actions[type]
if (!entry) {
return console.error('unknow actions type:' + type)
}
//传递一个上下文,其实就是当前的store实例
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 }
网友评论