# Vue3 中封装 useMapper 函数(Vuex)
# 作用
<script>
import { useStore } from "vuex";
import { computed } from "@vue/runtime-core";
export default {
setup() {
//1.传统方法在vuex中拿到state
const oldCounter = computed(() => store.state.counter);
const oldName = computed(() => store.state.name);
const oldAge = computed(() => store.state.age);
return {
oldCounter,
oldName,
oldAge,
};
},
};
</script>
<script>
import { useState } from "../hooks/useState";
export default {
setup() {
// 2.使用mapState封装的函数在vuex中拿到state
const storeState1 = useState(["counter", "name", "age"]);
return {
...storeState1,
};
},
};
</script>
# 实现代码
在 src 目录下创建 hooks 文件夹,在里面创建 useMapper.js
import {computed} from 'vue' | |
import { useStore } from 'vuex' | |
export function useMapper(mapper,mapFn){ | |
// 拿到 store 对象 | |
const store = useStore() | |
// 获取到相应的对象的 functions:{name:function,age:function} | |
const storeMapperFns = mapFn(mapper) | |
// 对数据进行转换 | |
const storeMapper = {} | |
Object.keys(storeMapperFns).forEach(fnKey=>{ | |
const fn = storeMapperFns[fnKey].bind({$store:store}) | |
storeMapper[fnKey] = computed(fn) | |
}) | |
return storeMapper | |
} |
在 src 目录下创建 hooks 文件夹,在里面创建 useState.js
// src/hooks/useState | |
import {useMapper} from './useMapper' | |
import { mapState , createNamespacedHelpers} from 'vuex' | |
export function useState(mapper,moduleName){ | |
let mapperFn = mapState | |
if(typeof moduleName === 'string' && moduleName.length > 0){ | |
mapperFn = createNamespacedHelpers(moduleName).mapState | |
} | |
return useMapper(mapper,mapperFn) | |
} |
# 测试使用
// src/app.vue
<template>
<div id="app">
<h1>使用useState方法通过数组拿到state数据</h1>
<h2>counter:{{counter}}</h2>
<h2>name:{{name}}</h2>
<h2>age:{{age}}</h2>
<hr>
<h1>使用useState方法通过对象拿到state数据</h1>
<h2>sCounter:{{sCounter}}</h2>
<h2>sName:{{sName}}</h2>
<h2>sAge:{{sAge}}</h2>
<hr>
<h1>使用useState方法通过对象拿到state数据</h1>
<h2>aCounter:{{aCounter}}</h2>
<h2>aName:{{aName}}</h2>
<h2>aAge:{{aAge}}</h2>
<hr>
<h1>使用传统方法拿到state数据</h1>
<h2>oldCounter:{{oldCounter}}</h2>
<h2>oldName:{{oldName}}</h2>
<h2>oldAge:{{oldAge}}</h2>
<hr>
<button @click="sub">-1</button>
<span>{{counter}}</span>
<button @click="add">+1</button>
</div>
</template>
<script>
import { useState } from "../hooks/useState";
import { useStore } from "vuex";
import { computed } from "@vue/runtime-core";
export default {
setup() {
// 使用mapState封装的函数拿到state
// 使用方法一:
const storeState1 = useState(["counter", "name", "age"]);
// 使用方法二:
const storeState2 = useState({
sCounter: (state) => state.counter,
sName: (state) => state.name,
sAge: (state) => state.age,
});
// 使用方法三:
const storeState3 = useState({
aCounter: "counter",
aName: "name",
aAge: "age",
});
// 拿到store对象
const store = useStore();
// 传统方法拿到state
const oldCounter = computed(() => store.state.counter);
const oldName = computed(() => store.state.name);
const oldAge = computed(() => store.state.age);
// 点击+1
const add = () => {
store.commit("increment");
};
// 点击-1
const sub = () => {
store.commit("decrement");
};
return {
...storeState1,
...storeState2,
...storeState3,
oldCounter,
oldName,
oldAge,
add,
sub,
};
},
};
</script>
<style lang="less">
#app {
text-align: center;
}
</style>