手写vuex4源码(三)vuex基本功能的实现

一、state

1、非响应式(错误)

直接将options的state赋值给state,这样数据是非响应式的

 constructor(options) {
        this.state = options.state
    }

手写vuex4源码(三)vuex基本功能的实现_第1张图片

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;
    }

手写vuex4源码(三)vuex基本功能的实现_第2张图片

二、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)
    }

你可能感兴趣的:(手写vuex4.x源码,vue.js,javascript,前端)