vue3.0下如何使用mapState,mapGetters和mapActions
vue2.0中使用mapState及mapActions的方式
// 使用mapState
computed:{...mapState({//...})}
methods:{...mapActions(['fnA','fnB'])}
vue3.0中获取state和使用actions的方式
import{computed}from'vue'import{useStore}from'vuex'setup(){const store=useStore();const stateA=computed(()=> store.state.stateA);const stateB=computed(()=> store.state.stateB);const methodA= store.dispatch('methodA',{name:'张三'});}
那如何才能在vue3下使用mapState这些api呢?
答案是封装mapState,mapGetters,mapActions方法。
1、新建useMapper.js
import{ useStore}from'vuex'import{ computed}from'vue'exportfunctionuseStateMapper(mapper, mapFn){const store=useStore();const storeStateFns=mapFn(mapper);const storeState={};
Object.keys(storeStateFns).forEach(fnKey=>{// vuex源码中mapState和mapGetters的方法中使用的是this.$store,所以更改this绑定const fn= storeStateFns[fnKey].bind({ $store: store});
storeState[fnKey]=computed(fn)})return storeState}exportfunctionuseActionMapper(mapper, mapFn){const store=useStore();const storeActionsFns=mapFn(mapper);const storeAction={};
Object.keys(storeActionsFns).forEach(fnKey=>{
storeAction[fnKey]= storeActionsFns[fnKey].bind({ $store: store})})return storeAction}
2、新建useState.js
import{ mapState, createNamespacedHelpers}from'vuex'import{ useStateMapper}from'./useMapper'import{checkType}from'./index'/**
*
* @param {*} moduleName 模块名称
* @param {*} mapper state属性集合 ['name', 'age']
* @returns
*/exportfunctionuseState(moduleName, mapper){let mapperFn= mapState;// 如果使用模块化,则使用vuex提供的createNamespacedHelpers方法找到对应模块的mapState方法if(checkType(moduleName)==="[object String]"&& moduleName.length>0){
mapperFn=createNamespacedHelpers(moduleName).mapState}returnuseStateMapper(mapper, mapperFn)}
3、新建useGetters.js
import{ mapGetters, createNamespacedHelpers}from'vuex'import{ useStateMapper}from'./useMapper'import{checkType}from'./index'/**
*
* @param {*} moduleName 模块名称
* @param {*} mapper getters属性集合 ['name', 'age']
* @returns
*/exportfunctionuseGetters(moduleName, mapper){let mapperFn= mapGetters;// 如果使用模块化,则使用vuex提供的createNamespacedHelpers方法找到对应模块的mapGetters方法if(checkType(moduleName)==="[object String]"&& moduleName.length>0){
mapperFn=createNamespacedHelpers(moduleName).mapGetters}returnuseStateMapper(mapper, mapperFn)}
4、新建useActions.js
import{ mapActions, createNamespacedHelpers}from'vuex';import{useActionMapper}from'./useMapper'import{checkType}from'./index'/**
*
* @param {*} moduleName 模块名称
* @param {*} mapper 方法名集合 ['fn1', 'fn2']
* @returns
*/exportfunctionuseActions(moduleName, mapper){let mapperFn= mapActions;// 如果使用模块化,则使用vuex提供的createNamespacedHelpers方法找到对应模块的mapActions方法if(checkType(moduleName)==="[object String]"&& moduleName.length>0){
mapperFn=createNamespacedHelpers(moduleName).mapActions}returnuseActionMapper(mapper, mapperFn)}
5、页面中使用
<template><divclass="home"><span>姓名:{{name}} 年龄:{{age}} 性别:{{sex}}</span><button @click="changeName">改名</button></div></template><script>// @ is an alias to /srcimport{useState}from'@/utils/useState'import{useActions}from'@/utils/useAction'exportdefault{
name:"home",setup(){const storeState=useState('home',['name','age','sex'])const storeActions=useActions('home',['setName'])constchangeName=()=>{
storeAction.setName('李四')}return{
changeName,...storeState,...storeActions};},};</script>