背景
vuex 也许是被 vue3.0 抛弃了,开始推 pinia 了,pinia 太过灵活,灵活就很容易失控,对于一个习惯了 vuex 严谨函数式设计思维的同学, vue3 对 vuex 的支持真是无法忍受,如何优雅的在 vue3 中 使用 vuex 呢?hooks 你值得拥有。
1:把 vuex 封装成一个 hooks, 命名为 useVuex.js
import { computed } from "vue";
import { createNamespacedHelpers, useStore } from "vuex";
const useFunctionHandle = (moduleName, mapper, mapFn) => {
let mapperFn = mapFn;
if (typeof moduleName === "string" && moduleName.length > 0) {
mapperFn = createNamespacedHelpers(moduleName)[mapFn];
} else {
mapper = moduleName;
}
const store = useStore();
const tempFns = mapperFn(mapper);
const storeFns = {};
Object.keys(tempFns).forEach((keyFn) => {
storeFns[keyFn] = tempFns[keyFn].bind({ $store: store });
});
return storeFns;
};
const useFunctionState = (moduleName, mapper, mapFn) => {
let mapperFn = mapFn;
if (typeof moduleName === "string" && moduleName.length > 0) {
mapperFn = createNamespacedHelpers(moduleName)[mapFn];
} else {
mapper = moduleName;
}
const store = useStore();
const tempFns = mapperFn(mapper);
const storeState = {};
Object.keys(tempFns).forEach((keyFn) => {
storeState[keyFn] = computed(() => tempFns[keyFn].call({ $store: store }));
});
return storeState;
};
export const useState = (moduleName, mapper) => {
return useFunctionState(moduleName, mapper, "mapState");
};
export const useGetters = (moduleName, mapper) => {
return useFunctionState(moduleName, mapper, "mapGetters");
};
// 使用 Composition API 创建类似于 mapActions 的函数
export const useActions = (moduleName, mapper) => {
return useFunctionHandle(moduleName, mapper, "mapActions");
};
// 使用 Composition API 创建类似于 mapMutations 的函数
export const useMutations = (moduleName, mapper) => {
return useFunctionHandle(moduleName, mapper, "mapMutations");
};
1:引用操作 vuex, 所有使用方式无限趋近于之前的 vuex 版本,真香,有没有?
import {
useState,
useGetters,
useActions,
useMutations,
} from "useVuex.js";
// 直接使用 State
const storeState = useState("demo", ["demoList"]);
// 换名使用 State
const { listStateNewName } = useState("demo", { listStateNewName: "demoList" });
// 直接使用 Getters
const { getList } = useGetters("demo", ["getList"]);
// 换名使用 Getters
const { listNewName } = useGetters("demo", { listNewName: "getList" });
// 直接使用 Actions
const { addAction } = useActions("demo", ["addAction"]);
addAction({ a: 9 });
// 重命令 Actions
const { addAc } = useActions("demo", { addAc: "addAction" });
addAc({ a: 99 });
addAc({ a: 922 });
// 直接使用 Mutations
const { addMutation, removeMutaion } = useMutations("demo", [
"addMutation",
"removeMutaion",
]);
addMutation({ b: 666 });
removeMutaion({ id: "008" });
// 重命名 Mutations
const { add, remove } = useMutations("demo", {
add: "addMutation",
remove: "removeMutaion",
});