一、state
1、非响应式(错误)
直接将options的state赋值给state,这样数据是非响应式的
constructor(options) {
this.state = options.state
}
2、响应式(正确)
vuex3内部会创造一个vue实例,但是vuex4直接采用vue3提供的响应式方法:reactive
将数据变成响应式后,用户获取数据时通过类的属性访问器返回给用户
- 为什么需要{data:options.state}使用data?
- vuex中的replaceState可以修改整个vuex数据的功能,所以需要加上一层data
- 如果没有data 在修改的时候修改store._state,还需要使用reactive包一层
- 存在data,则可以使用store._state.data = xxx 直接修改
constructor(options) {
// vuex3内部会创造一个vue实例,但是vuex4直接采用vue3提供的响应式方法
const store = this
// store._state.data
store._state = reactive({ data: options.state })
}
// 用户去取值state,走到这里,返回store上的_state 类的属性访问器
get state() {
return this._state.data;
}
二、getters
getters也是返回一个属性,把options中的getters循环遍历到store.getters身上,并使用defineproperty添加响应式
会带来性能问题,每次只取值也会执行
- 使用计算属性优化getter的问题:官方pr
我们面临的问题是,当组件被销毁时,getter(计算的)会通过Vue被销毁。因此,如果我们在组件内部调用registerModule,那么当该组件被破坏时,任何新注册的计算都将消失,例如,在切换路由时。
const _getters = options.getters;
store.getters = {}
forEachValue(_getters, function (fn, key) {
// 性能问题,每次取值都会执行,多次取值不执行使用computed,在vue3.1不能使用computed,因为组件销毁了,会移除计算属性
Object.defineProperty(store.getters, key, {
enumerable:true,
get: () => fn(store.state)
})
})
三、mucation和cation
store._mutations = Object.create(null);
store._actions = Object.create(null);
const _mutations = options.mutations;
const _actions = options.actions;
forEachValue(_mutations, (mutation, key) => {
store._mutations[key] = (payload) => {
mutation.call(store, store.state, payload);
}
})
forEachValue(_actions, (action, key) => {
store._actions[key] = (payload) => {
action.call(store, store, payload);
}
})
commit = (type, payload) => { // bind 方法
this._mutations[type](payload)
}
dispatch = (type, payload) => {
this._actions[type](payload)
}