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

文章详细阐述了Vuex4中如何使state变得响应式,包括使用`reactive`包裹state以实现响应式,以及在处理getters时遇到的性能问题,提出了使用计算属性进行优化。同时,介绍了如何设置mutations和actions,以及commit和dispatch的方法。
摘要由CSDN通过智能技术生成

一、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)
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值