Vue3中使用vuex的辅助函数mapState、mapGetters等一些记录

1,538 阅读1分钟

文章前提纪要说明

  • 本文使用的封装思想灵感皆来自于coderwhy
  • 以下附截图加部分说明作为学习模板记录

记录1

  • Vue3中自v3.2版本开始大家更倾向使用setup语法糖
  • 组合式API(Composition API)setup() 函数中手动暴露(return)大量的状态和方法非常繁琐。当使用单文件组件(SFC)时,我们可以使用 <script setup> 来大幅度地简化代码,也就是我们说的语法糖。
  • Vue3有兴趣的同学可以自行学习了解探索更有趣的变化

记录2

  • 使用 <script setup>如何更加高效使用vuex的映射函数,以下记录部分代码封装注释
  • 通过Vue-cli脚手架创建的vue项目,选择了vuex则根目录src下会有store文件夹,若创建项目未选择vuex也不打紧,我们开发通常自行安装vuex依赖的包后,会自行在src下手动创建store文件夹
  • vue3现在结合使用状态管理仓库一般都会选择Pinia,此篇暂时用vuex记录一些封装代码供参考
  • vuex的store主要包括五个模块,{ state, getters, mutations, actions, modules }
    • 此篇记录mutations开发的一些小技巧和封装
    • store下新建文件夹存放调用mutations的方法commit时的方法名
    • 提交 mutations 的另一种写法,主要是为了解决vue文件定义的方法名字容易和store里不一致问题

image.png

image.png

export const CHANGE_NAME = 'changeName';
  • store中举例使用
// store中举例调用定义好的mutations方法名字
import { createStore } from 'vuex';
import { CHANGE_NAME } from './store-types/mutations-type';

export default createStore({
    state: {},
    getters: {},
    mutations: {
        [CHANGE_NAME]: (state, payload) => {
            state.name = payload.name;
        },
    },
    actions: {},
    modules: {},
});
  • vue文件中使用
<script setup>
import { useStore } from 'vuex';
import { CHANGE_NAME } from '@/store/store-types/mutations-type';

const store = useStore();
const changeName = () => {
    // 第一种常见写法
    // store.commit(CHANGE_NAME, { name: 'codeWhite' });
    // 第二种常见写法
    store.commit({
        type: CHANGE_NAME,
        name: 'codeWhite',
    });
};
</script>

映射函数的封装使用

  • 封装hooks方便调用

image.png

  • index.js将hooks统一管理对外暴露
import { useStateMap } from './useStateMap';
import { useGetterMap } from './useGetterMap';

export { useStateMap, useGetterMap };
  • useMapper.js依赖computed计算的映射函数统一封装
import { useStore } from 'vuex';
import { computed } from 'vue';

// 对 vue3 使用 mapState、mapGetters 的封装
export function useStoreMap(mapper, useMap) {
    // 获取 store 独享
    const store = useStore();
    // 获取对应的对象的function: {name: function, age: function}
    const storeStateFns = useMap(mapper);
    // 对数据进行转换
    const storeState = {};
    Object.keys(storeStateFns).forEach((Fnkey) => {
        // setup中无 this 指向,在 computed 中计算state时需要 $store 指向,所以使用 bind() 绑定 $store
        const fn = storeStateFns[Fnkey].bind({ $store: store });
        storeState[Fnkey] = computed(fn);
    });
    // 返回值
    return storeState;
}
  • useStateMap.js
import { useStoreMap } from './useMapper';
import { mapState } from 'vuex';

export function useStateMap(mapper) {
    return useStoreMap(mapper, mapState);
}
  • useGetterMap.js
import { useStoreMap } from './useMapper';
import { mapGetters } from 'vuex';

export function useGetterMap(mapper) {
    return useStoreMap(mapper, mapGetters);
}
  • vue文件中使用
<script setup>
import { useStore } from 'vuex';
import { useStateMap } from '@/hooks/store-hooks/index';
import { CHANGE_NAME } from '@/store/store-types/mutations-type';

// 第一种使用辅助函数:传入数组
const storeStateArr = useStateMap(['name', 'age', 'sex']);
// 第二种使用辅助函数:传入对象,可以避免参数名重复
// const storeStateObj = useStateMap({
//     xInfo: (state) => state.userInfo,
// });

const store = useStore();
const changeName = () => {
    // store.commit(CHANGE_NAME, { name: 'codeWhite' });
    // 提交 mutations 的另一种写法 主要是为了解决 定义方法名字容易和 store 里的写错问题
    store.commit({
        type: CHANGE_NAME,
        name: 'codeWhite',
    });
};
</script>

记录3:Getters同理如上

  • getters除了可以返回具体的值,也可以returnfunction可以更灵活入参!

此篇结束