原文网址:Vuex--module(模块化)--使用/教程/实例_IT利刃出鞘的博客-CSDN博客
简介
说明
本文用示例介绍Vuex的五大核心之一:module。
官网
module概述
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用非常复杂时,store 对象可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块(从上至下进行同样方式的分割)。
用法
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
示例
创建两个模块:Counter.js(计数器模块)、UserInfo.js(用户信息模块),使用CommonStore.js将这两个模块注册到Vuex。
代码结构:
公共代码
Counter.js(计数器模块)
const counter = {
namespaced: true,
// 这里的 state 对象是模块的局部状态
state: {
count: 10,
info: 'This is counter'
},
getters: {
doubleCount(state) {
return state.count * 2;
}
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
}
},
actions: {
asyncIncrement(context) {
console.log('CounterStore=> action: asyncIncrement');
setTimeout(() => {
context.commit('increment')
}, 1000)
},
}
}
export default counter;
UserInfo.js
const userInfo = {
namespaced: true,
state: {
userName: '',
authorization: ''
},
mutations: {
writeUserName(state, name) {
// 这里的 `state` 对象是模块的局部状态
state.userName = name;
},
writeAuthorization(state, auth) {
// 这里的 `state` 对象是模块的局部状态
state.authorization = auth;
},
}
}
export default userInfo;
Parent.vue(入口组件)
<template>
<div class="outer">
<h3>父组件</h3>
<component-a></component-a>
<component-b></component-b>
</div>
</template>
<script>
import ComponentA from "./ComponentA";
import ComponentB from "./ComponentB";
export default {
name: 'Parent',
components: {ComponentA, ComponentB},
}
</script>
<style scoped>
.outer {
margin: 20px;
border: 2px solid red;
padding: 20px;
}
</style>
路由(router/index.js)
import Vue from 'vue'
import Router from 'vue-router'
import Parent from "../components/Parent";
Vue.use(Router)
export default new Router({
routes: [
{
path: '/parent',
name: 'Parent',
component: Parent,
}
],
})
写法1:基础写法
代码
ComponentA.vue(写数据)
<template>
<div class="container">
<h3>ComponentA</h3>
<button @click="incrementCounter">计数器加1</button>
<button @click="asyncIncrementCounter">计数器异步加1</button>
</div>
</template>
<script>
export default {
methods: {
incrementCounter() {
this.$store.commit('module1/increment')
},
asyncIncrementCounter() {
this.$store.dispatch('module1/asyncIncrement')
},
}
}
</script>
<style scoped>
.container {
margin: 20px;
border: 2px solid blue;
padding: 20px;
}
</style>
ComponentB.vue
<template>
<div class="container">
<h3>ComponentB</h3>
<div>计数器的值:{{thisCount}}</div>
<div>计数器的2倍:{{thisDoubleCount}}</div>
</div>
</template>
<script>
export default {
computed:{
thisCount() {
return this.$store.state.module1.count;
},
thisDoubleCount() {
return this.$store.getters["module1/doubleCount"];
},
}
}
</script>
<style scoped>
.container {
margin: 20px;
border: 2px solid blue;
padding: 20px;
}
</style>
测试
访问:http://localhost:8080/#/parent
写法2:map写法
代码
ComponentA.vue(写数据)
<template>
<div class="container">
<h3>ComponentA</h3>
<button @click="increment">计数器加1</button>
<button @click="asyncIncrement">计数器异步加1</button>
</div>
</template>
<script>
import {mapMutations, mapActions} from 'vuex'
export default {
methods: {
...mapMutations('module1', ["increment", "decrement"]),
...mapActions('module1', ["asyncIncrement"])
}
}
</script>
<style scoped>
.container {
margin: 20px;
border: 2px solid blue;
padding: 20px;
}
</style>
ComponentB.vue(读数据)
<template>
<div class="container">
<h3>ComponentB</h3>
<div>计数器的值:{{ count }}</div>
<div>计数器的2倍:{{ doubleCount }}</div>
</div>
</template>
<script>
import {mapState, mapGetters} from 'vuex'
export default {
computed: {
...mapState('module1', ['count', 'info']),
...mapGetters('module1', ['doubleCount'])
}
}
</script>
<style scoped>
.container {
margin: 20px;
border: 2px solid blue;
padding: 20px;
}
</style>
测试
访问: http://localhost:8080/#/parent
写法3:map+Helper
createNamespacedHelpers 是命名空间辅助函数,用来规定辅助函数的路径。它可以用来控制只使用某个模块。
本处测试只引入计数器(Counter.js)模块。
代码
ComponentA.vue(写数据)
<template>
<div class="container">
<h3>ComponentA</h3>
<button @click="increment">计数器加1</button>
<button @click="asyncIncrement">计数器异步加1</button>
</div>
</template>
<script>
import {createNamespacedHelpers} from "vuex";
const {mapMutations, mapActions} = createNamespacedHelpers('module1');
export default {
methods: {
...mapMutations(["increment", "decrement"]),
...mapActions(["asyncIncrement"])
}
}
</script>
<style scoped>
.container {
margin: 20px;
border: 2px solid blue;
padding: 20px;
}
</style>
ComponentB.vue(读数据)
<template>
<div class="container">
<h3>ComponentB</h3>
<div>计数器的值:{{ count }}</div>
<div>计数器的2倍:{{ doubleCount }}</div>
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex'
const {mapState, mapGetters} = createNamespacedHelpers('module1');
export default {
computed: {
...mapState(['count', 'info']),
...mapGetters(['doubleCount'])
}
}
</script>
<style scoped>
.container {
margin: 20px;
border: 2px solid blue;
padding: 20px;
}
</style>
测试
访问:http://localhost:8080/#/parent
其他网址
VueX mapGetters 获取 Modules 中的Getters_静已思之愈浓的博客-CSDN博客