Vuex模块化编码使用详解
作者:yume_sibai
本文介绍了 Vuex 的模块化和命名空间功能,通过对 store.js 进行模块划分,提高代码维护性和数据分类的明确性,并讲解了在组件中读取和操作模块化 state、getters、actions、mutations 的具体方法
一、模块化+命名空间
1.目的:让代码更好维护,让多种数据分类更加明确。
2.修改store.js
const countAbout = {
namespaced:true,//开启命名空间
state:{x:1},
mutations: { ... },
actions: { ... },
getters: {
bigSum(state){
return state.sum * 10
}
}
}
const personAbout = {
namespaced:true,//开启命名空间
state:{ ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
countAbout,
personAbout
}
})3.开启命名空间后,组件中读取state数据:
//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取
...mapState('countAbout',['sum','school','subject']),4.开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取
...mapGetters('countAbout',['bigSum'])5.开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'incrementOdd',incrementWait:'incrementWait'})6.开启命名空间后,组件中调用commit
//方式一:自己直接commit
this.$store.commit('personAbout/PERSON_ADD',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'INCREMENT',decrement:'DECREMENT'}),二、代码实现
将求和相关配置写入countAbout.js中。
export default {
namespaced:true,
actions:{
incrementOdd(context,value){
if(context.state.sum % 2)
context.commit('INCREMENTODD',value)
},
incrementWait(context,value){
setTimeout(() => {
context.commit('INCREMENTWAIT',value)
}, 500);
}
},
mutations:{
INCREMENT(state,value){
state.sum +=value
},
DECREMENT(state,value){
state.sum -=value
},
INCREMENTODD(state,value){
state.sum +=value
},
INCREMENTWAIT(state,value){
state.sum +=value
},
},
state:{
sum:0,
school:'清华大学',
subject:'Vue',
},
getters:{
bigSum(state){
return state.sum*10
}
}
}将求和相关配置写入personAbout.js中。
import axios from 'axios'
import { nanoid } from 'nanoid'
export default {
namespaced:true,
actions:{
personAddWang(context,value){
if(value.name.indexOf('王') === 0){
context.commit('PERSON_ADD',value)
}
else{
alert('请添加姓王的人')
}
},
personAddServer(context){
axios.get('https://www.openapijs.com/api/random').then(
Response=>{
context.commit('PERSON_ADD',{id:nanoid(),name:Response.data.data.poems.autho})
},
Error=>{
alert(Error.message)
}
)
}
},
mutations:{
PERSON_ADD(state,value){
state.personList.unshift(value)
}
},
state:{
personList:[{
id:'001',
name:'张三'
}]
},
getters:{
firstPersonName(state){
return state.personList[0].name
}
}
}
将countAbout和personAbout引入index.js中。
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countAbout from './countAbout'
import personAbout from './personAbout'
//应用Vuex插件
Vue.use(Vuex)
//创建并暴露store
export default new Vuex.Store({
modules:{
countAbout,
personAbout
}
})模块化后,在vue文件中不同的引用方法,在Count.js中使用map引用:
<template>
<div class="main">
<h1>这门课是{{ school }}的{{ subject }}课程</h1>
<h2>当前求和为:{{ sum }}</h2>
<h3>当前求和放大十倍为:{{ bigSum }}</h3>
<h3 style="color: red;">当前人数为:{{ personList.length }}</h3>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="INCREMENT(n)">+</button>
<button @click="DECREMENT(n)">-</button>
<button @click="incrementOdd(n)">当前为奇数再加</button>
<button @click="incrementWait(n)">等会再加</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
name:'Count',
data() {
return {
n:1
}
},
methods: {
...mapMutations('countAbout',['INCREMENT','DECREMENT']),
...mapActions('countAbout',['incrementOdd','incrementWait']),
},
computed:{
...mapState('countAbout',['sum','school','subject']),
...mapState('personAbout',['personList']),
...mapGetters('countAbout',['bigSum'])
}
}
</script>
<style lang="less" scoped>
button{
margin-left: 5px;
}
</style>在Person.js中使用手动引用:
<template>
<div>
<h2>人员列表</h2>
<h3 style="color: red;">Count组件的总和为:{{ sum }}</h3>
<h3>列表第一个人名为:{{ firstPersonName }}</h3>
<input type="text" v-model="person">
<button @click="personAdd">点击添加</button>
<button @click="personAddWang">添加一个姓王的人</button>
<button @click="personAddServer">随机添加一个人</button>
<ul>
<li v-for="p in personList" :key="p.id">{{ p.name }}</li>
</ul>
</div>
</template>
<script>
import { nanoid } from 'nanoid'
export default {
name:'Persons',
data() {
return {
person:''
}
},
methods: {
personAdd(){
const obj = {id:nanoid(),name:this.person}
this.$store.commit('personAbout/PERSON_ADD',obj)
this.person=''
},
personAddWang(){
const obj = {id:nanoid(),name:this.person}
this.$store.dispatch('personAbout/personAddWang',obj)
this.person=''
},
personAddServer(){
this.$store.dispatch('personAbout/personAddServer')
}
},
computed:{
personList(){
return this.$store.state.personAbout.personList
},
sum(){
return this.$store.state.countAbout.sum
},
firstPersonName(){
return this.$store.getters['personAbout/firstPersonName']
}
}
}
</script>
<style lang="less">
ul{
font-size: 18px;
li{
padding-top: 5px;
}
}
</style>总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
