目录
4. 如果删除moduleA的namespaced属性, 保留moduleB的namespaced:true
6. 使用mapGetters和mapActions的情况:
1. store/index.ts
注意: 需要使用时带上模块名称的namespaced必须为true, 不写或者为false时调用时不需要写模块名称(获取state的值必须加模块名)
import { createStore } from "vuex";
// A模块
const moduleA = {
namespaced: true,
state: {
name: "moduleA",
},
getters: {
newName(state) {
return state.name;
},
},
mutations: {
changeName(state, payload) {
state.name = payload;
},
updateAge(state, playLoad) {
state.age = playLoad;
},
},
actions: {
changeAge({ commit }, age) {
setTimeout(() => {
commit("updateAge", age);
}, 0);
},
},
};
// B模块
const moduleB = {
namespaced: true,
state: {
name: "moduleB",
age: 33,
},
getters: {
newName(state) {
return state.name;
},
},
mutations: {
changeName(state, payload) {
state.name = payload;
},
updateAge(state, playLoad) {
console.log("playLoad", playLoad);
state.age = playLoad;
},
},
actions: {
changeAge(ctx, count) {
console.log("触发了-模块B的action");
setTimeout(() => {
ctx.commit("updateAge", count);
}, 1000);
},
},
};
export default createStore({
// 分模块
modules: {
moduleA,
moduleB,
},
});
2. main.ts
import { createApp } from "vue";
import App from "./App.vue";
import * as Vue from "vue";
import store from './store';
const app = createApp(App);
app.use(store);
app.mount("#app");
3. App.vue调用
<template>
<div id="container">
<!-- 1、使用A模块的state数据 -->
<div>
姓名: <input type="text" @change="changeAName($event)">
</div>
<div>
年龄: <input type="number" @change="changeAAge($event)">
</div>
<h1>模块a:</h1>
<p>姓名(state): {{ store.state.moduleA.name }}</p>
<!-- 2、使用A模块的getters数据 -->
<p>姓名(getters): {{ store.getters["moduleA/newName"] }}</p>
<p>年龄: {{ store.state.moduleA.age }}</p>
<!-- 1、使用B模块的state数据 -->
<h1>模块b:</h1>
<div>
姓名: <input type="text" @change="changeBName($event)">
</div>
<div>
年龄: <input type="number" @change="changeBAge($event)">
</div>
<p>姓名(state): {{ store.state.moduleB.name }}</p>
<!-- 2、使用B模块的getters数据 $store.getters['模块名/计算属性']-->
<p>姓名(getters): {{ store.getters["moduleB/newName"] }}</p>
<p>年龄: {{ store.state.moduleB.age }}</p>
</div>
</template>
<script setup lang="ts">
import { useStore } from "vuex";
// userStore可以拿到vuex仓库实例
const store = useStore();
const changeAName = (e) => {
store.commit('moduleA/changeName', e.target.value)
};
const changeAAge = (e) => {
store.dispatch("moduleA/changeAge", e.target.value)
};
const changeBName = (e) => {
// 提交B模块的更改
store.commit('moduleB/changeName', e.target.value)
};
const changeBAge = (e) => {
// 传参用法
store.dispatch("moduleB/changeAge", e.target.value)
};
</script>
<style lang='scss' scoped></style>
4. 如果删除moduleA的namespaced属性, 保留moduleB的namespaced:true
import { createStore } from "vuex";
// A模块
const moduleA = {
state: {
name: "moduleA",
},
getters: {
newName(state) {
return state.name;
},
},
mutations: {
changeName(state, payload) {
state.name = payload;
},
updateAge(state, playLoad) {
state.age = playLoad;
},
},
actions: {
changeAge({ commit }, age) {
setTimeout(() => {
commit("updateAge", age);
}, 0);
},
},
};
// B模块
const moduleB = {
namespaced: true,
state: {
name: "moduleB",
age: 33,
},
getters: {
newName(state) {
return state.name;
},
},
mutations: {
// 更改数据函数
changeName(state, payload) {
state.name = payload;
},
updateAge(state, playLoad) {
console.log("playLoad", playLoad);
state.age = playLoad;
},
},
actions: {
changeAge(ctx, count) {
setTimeout(() => {
ctx.commit("updateAge", count);
}, 1000);
},
},
};
export default createStore({
// 分模块
modules: {
moduleA,
moduleB,
},
});
5. 则App.vue修改为:
<template>
<div id="container">
<!-- 1、使用A模块的state数据 -->
<div>
姓名: <input type="text" @change="changeAName($event)">
</div>
<div>
年龄: <input type="number" @change="changeAAge($event)">
</div>
<h1>模块a:</h1>
<p>姓名(state): {{ store.state.moduleA.name }}</p>
<p>姓名(getters): {{ store.getters["newName"] }}</p>
<p>年龄: {{ store.state.moduleA.age }}</p>
<!-- 1、使用B模块的state数据 -->
<h1>模块b:</h1>
<div>
姓名: <input type="text" @change="changeBName($event)">
</div>
<div>
年龄: <input type="number" @change="changeBAge($event)">
</div>
<p>姓名(state): {{ store.state.moduleB.name }}</p>
<!-- 2、使用B模块的getters数据 $store.getters['模块名/计算属性']-->
<p>姓名(getters): {{ store.getters["moduleB/newName"] }}</p>
<p>年龄: {{ store.state.moduleB.age }}</p>
</div>
</template>
<script setup lang="ts">
import { useStore } from "vuex";
// userStore可以拿到vuex仓库实例
const store = useStore();
const changeAName = (e) => {
store.commit('changeName', e.target.value)
};
const changeAAge = (e) => {
store.dispatch("changeAge", e.target.value)
};
const changeBName = (e) => {
store.commit('moduleB/changeName', e.target.value)
};
const changeBAge = (e) => {
store.dispatch("moduleB/changeAge", e.target.value)
};
</script>
<style lang='scss' scoped></style>
6. 使用mapGetters和mapActions的情况:
store/vuexHelper.ts
原理: 使用bind改变this的指向, 且相当于() => fn, 所以可以使用computed钩子
import { computed } from "vue";
export const getStateOrGettersMap = (store, mappers) => {
const obj = {};
Object.keys(mappers).forEach((key) => {
obj[key] = computed(mappers[key].bind({ $store: store })).value;
});
return obj;
};
export const formatterActionsMap = (store, actions) => {
Object.keys(actions).forEach((fnKey) => {
actions[fnKey] = actions[fnKey].bind({ $store: store });
});
};
App.vue
<template>
<div id="container">
<!-- 1、使用A模块的state数据 -->
<div>
姓名: <input type="text" @change="changeAName($event)">
</div>
<div>
年龄: <input type="number" @change="changeAAge($event)">
</div>
<h1>模块a:</h1>
<p>姓名(state): {{ store.state.moduleA.name }}</p>
<p>姓名(getters): {{ store.getters["newName"] }}</p>
<p>姓名(mapGetters): {{ mapAData.newName }}</p>
<p>年龄: {{ store.state.moduleA.age }}</p>
<!-- 1、使用B模块的state数据 -->
<h1>模块b:</h1>
<div>
姓名: <input type="text" @change="changeBName($event)">
</div>
<div>
年龄: <input type="number" @change="changeBAge($event)">
</div>
<p>姓名(state): {{ store.state.moduleB.name }}</p>
<p>姓名(getters): {{ store.getters["moduleB/newName"] }}</p>
<p>姓名(mapGetters): {{ mapBData.newName }}</p>
<p>年龄: {{ store.state.moduleB.age }}</p>
</div>
</template>
<script setup lang="ts">
import { useStore, mapGetters, mapActions } from 'vuex';
import { computed } from 'vue'
import { getStateOrGettersMap, formatterActionsMap } from './store'
// userStore可以拿到vuex仓库实例
const store = useStore();
const changeAName = (e) => {
store.commit('changeName', e.target.value)
};
const changeAAge = (e) => {
store.dispatch("changeAge", e.target.value)
};
const aMappers = mapGetters(['newName'])
const mapAData = computed(() => getStateOrGettersMap(store, aMappers))
const changeBName = (e) => {
// 提交B模块的更改
store.commit('moduleB/changeName', e.target.value)
};
const changeBActions = mapActions('moduleB', ['changeAge'])
formatterActionsMap(store, changeBActions)
const changeBAge = (e) => {
changeBActions.changeAge(e.target.value)
// store.dispatch("moduleB/changeAge", e.target.value)
};
const bMappers = mapGetters('moduleB', ['newName'])
const mapBData = computed(() => getStateOrGettersMap(store, bMappers))
</script>
<style lang='scss' scoped></style>