持续创作,加速成长!这是我参与「掘金日新计划 · 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是这样
里面有counter,name,age三个属性,现在需要在setup中使用,先用mapState把属性导出,此时的数据是key-value形式,value为函数
我们看一下此时的name,不出意外是一个函数
确实是一个函数,我们用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老师教程里学习的,有不对的欢迎大家指出,看到这里给个赞吧,谢谢喽,爱你