上一篇文章我们介绍了vuex的基本使用方法,但是当你项目比较大,vuex的数据比较多,使用过程中,你就会发现,有很多问题
第一个问题是:
数据不太容易维护
改进方案:
因为你的所有同步和异步方法都写在了一个index.js文件中,其实我们可以通过modules划分来解决这个问题
第二个问题是:
我们获取数据,更改数据代码过于繁琐
之前写法如下:
获取数据时:使用 this.$store.state.xxx
提交同步方法时:使用 this.$store.commit(“xxx”)
提交异步方法时:使用 this.$store.dispatch(“xxx”)
改进方法:
使用mapState, mapMutations, mapActions语法糖
具体使用如下:
1、在src目录下新建store文件夹,在store文件夹下新建index.js文件,新建modules文件夹,modules文件夹下新建oneTest.js,twoTest.js 两个文件,目录层次如下图:
2、main.js引用
import store from './store'
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
3、index.js下代码如下:
import Vue from 'vue'
import Vuex from 'vuex'
import oneTest from './modules/oneTest.js' //引入此模块
import twoTest from './modules/twoTest.js'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
oneTest, //导出此模块
twoTest
}
})
4、oneTest.js代码如下:
const oneTest = {
namespaced: true, // 创建命名空间
state: { // 存储变量
flag: false,
num: 10
},
mutations: { // 定义修改state方法
changeSum: (state, params) => {
state.num = state.num + params
},
//是否展示图片
showImg: (state) => {
state.flag = !state.flag
},
//同步执行打印方法
asyncFun() {
console.log(888)
}
},
actions: {
asyncFun({ commit }) { //这种写法是结构赋值;此处原本写法是接收context参数,下方使用context.commit("asyncFun")调用
setTimeout(() => {
commit("asyncFun"); //调用mutations内的同步方法
}, 2000);
console.log("我比asyncFun提前执行");
}
},
getters: { // 将数据过滤输出
bodyShow: state => state.showAlert
}
}
export default oneTest
5、页面里调用代码:
<template>
<div class="box">
<div>
<button @click="tap">点击数字加5</button>
结果:
{{num}}
</div>
<div>
<button @click="tapShowImg">点击展示下方图片</button>
<img src="https://img.alicdn.com/imgextra/i3/114052057/O1CN015yyAY91R49P9C4vbl_!!0-saturn_solar.jpg_468x468q75.jpg_.webp" alt="" v-if="flag">
</div>
<div>
<button @click="tapChangeAge">异步打印</button>
</div>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from "vuex";
//都是语法糖,vuex封装好的方法,以便于我们更好的获取数据,修改数据
//之所以使用是为了简化代码量,不然就要不停的this.$store.state.oneTest.num,
//this.$store.commit("oneTest/xxx"),this.$store.dispatch("oneTest/xxx");
export default {
data() {
return {
sum: 5,
};
},
computed: {
//oneTest是index.js里export导出的模块名,要一致
//num和flag是oneTest模块下的state数据名,相当于接收oneTest模块下的数据
...mapState("oneTest", ["num", "flag"]),
},
mounted() {},
methods: {
//oneTest是index.js里export导出的模块名,要一致,changeSum和showImg是此模块下的同步方法名
//如果没有modules划分的话,是这样写...mapMutations(["changeSum","showImg"])
...mapMutations("oneTest", ["changeSum", "showImg"]),
//mapActions方法和mapMutations使用方法一样的
...mapActions("oneTest", ["asyncFun"]),
//点击数字加5
tap() {
this.changeSum(5);
},
//点击展示下方图片
tapShowImg() {
this.showImg();
},
tapChangeAge() {
this.asyncFun();
},
},
};
</script>
<style scoped>
.box > div {
margin: 30px 0;
}
img {
width: 100px;
height: 100px;
}
</style>
`