在 Vue3 的 setup 语法中,不方便使用 Vuex 为 options api 提供的 mapState 和 mapMutaions 辅助方法。为了方便在 setup 下使用,可以选择封装 mapState 和 mapMutaion 的 hooks。
下面是Typescript的写法,展示了 useMapState Hook 的实现:
interface useMapStateRet {
[x: string]: ComputedRef<any>;
}
/**
* setup下不容易直接使用mapState,使用hook封装mapState
*/
export function useMapState(map: any) {
const store = useStore()
const computeds = mapState(map)
const stateComputeds: useMapStateRet = {}
Object.keys(computeds).forEach(fnName => {
// 这里需要注意,需要用Bind使得计算属性中的this.$store指向store实例
const fn = computeds[fnName].bind({ $store: store })
// mapState返回是还是一个函数集合对象,
// 为了兼容composition api,同时保证vuex变量被准确的作为依赖收集
// 需要用computed包裹每一个函数
stateComputeds[fnName] = computed<any>(fn)
})
return stateComputeds
}
<div v-if="headerShow" class="header-wrapper">
<img v-show="bannerUrl" class="header-img" :src="bannerUrl" />
</div>
与之类似的,mapMutations同样也可以这样封装。不要忘记改变 this.$store 的访问指向为 store 实例。
/**
* setup下不容易直接使用mapMutations,使用hook封装mapMutations
*/
export function useMapMutations(map: any) {
const store = useStore()
const methods = mapMutations(map)
Object.keys(methods).forEach(fnName => {
methods[fnName] = methods[fnName].bind({ $store: store })
})
return methods
}
// vue3 setup 函数环境中
const { setOutboundStatus, setTrialTime } = useMapMutations({
setOutboundStatus: SET_OUTBOUND_STATUS,
setTrialTime: SET_TRIAL_TIME
})
setTrialTime({ startTime, remainingSeconds })
setOutboundStatus(APPLY_UNSTART_TRIAL_GOING)