vue3封装vuex的getters和state函数

135 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

问题

在setup中使用vuex的mapState和mapGetters函数,我们无法像在vue2的computed那样的丝滑,在setup函数中,如果需要的state和getter函数过多,我们需要一天条一条去写,然后return导出,十分的浪费时间,并且一点不简洁,那么有没有一种可能我们写一个函数,直接像vue2那样可以直接导出,不用一条一条写

思路

mapState和mapGetters接受一个参数,对象或者数组,返回一个对象,key为传入的值,value为一个函数,在vue2中只需要把mapState的对象解析到computed中接可以使用,在setup中computed只能接收一个函数,无法批量添加,那么我们就可以拿到所有的函数名,也就是mapState返回的对象的key,对他进行遍历,让后把每一个函数都使用computed包裹,然后存储到一个对象里面,再把这个对象return出去,就可以批量完成store中的数据导出

实现

先创建一个store,此时我的store是这样

store状态.png

里面有counter,name,age三个属性,现在需要在setup中使用,先用mapState把属性导出,此时的数据是key-value形式,value为函数

使用mapState.png

我们看一下此时的name,不出意外是一个函数

map函数.png

确实是一个函数,我们用Object.keys()方法获取storeState中所有的的key,进行遍历添加computed

setup() {
    const store = useStore()
    const storeState = mapState(["counter","name","age"])
    const state = {}
    Object.keys(storeState).forEach((keyFn)=>{
      const fn = storeState[keyFn].bind({$store:store})
      state[keyFn] = computed(fn)
    })
    return {
      ...state
    }
}

注意在调用storeState[keyFn]必须给他指定$store,不然会报错,这样我们就可以拿到所有的state中的属性了,此时我们还可以在优化一点

优化

我们可以把这个函数抽离出去,单独封装成一个hook

export function useState(mapper){
    const store = useStore()
    const storeStateFn = mapState(mapper)
    const storeState = {}
    Object.keys(storeStateFn).forEach(fnKey => {
        const fn = storeStateFn[fnKey].bind({$store:store})
        storeState[fnKey] = computed(fn)
    })
    return storeState
}

hook useState接收一个参数mapper,处理后返回一个对象storeState,里面就是我们需要的数据,同理,我们对getters一样可以封装,而mutation就不需要了,它可以在setup中直接用mapMutation直接导出 同样我们还可以把这个和getter的hook公共代码抽离出来,重新封装成useMapper

export  function useMapper(mapper,mapFn){
    const store = useStore()
    const storeStateFn = mapFn(mapper)
    const storeState = {}
    Object.keys(storeStateFn).forEach(fnKey => {
        const fn = storeStateFn[fnKey].bind({$store:store})
        storeState[fnKey] = computed(fn)
    })
    return storeState
}

useMapper接受两个参数,第一个是传来需要处理的对象,第二个是类型

封装完成后我们可以直接使用import在useState中引用

import { mapState } from "vuex"
import useMapper from "./useMapper"
export  function useState(mapper){
    return useMapper(mapper,mapState)
}

一样可以使用

结束

这个是codewhy老师教程里学习的,有不对的欢迎大家指出,看到这里给个赞吧,谢谢喽,爱你