因为在大多数的项目中,我们对于全局状态的管理并不仅仅一种情况的需求,有时有多方面的需求,比如写一个商城项目,你所用到的全局state可能是关于购物车这一块儿的也有可能是关于商品价格这一块儿的;像这样的情况我们就要考虑使用vuex中的 modules 模块化了,具体怎么使用modules呢?咱们继续一步一步的走:
首先,在store文件夹下面新建一个modules文件夹,然后在modules文件里面建立需要管理状态的js文件,既然要把不同部分的状态分开管理,那就要把它们给分成独立的状态文件了,如下图:
而对应的store文件夹下面的index.js 里面的内容就直接改写成:
import Vue from 'vue';import Vuex from 'vuex';import footerStatus from './modules/footerStatus'import collection from './modules/collection'Vue.use(Vuex);export default new Vuex.Store({modules:{footerStatus,collection}});相应的js,其中的 namespaced:true 表示当你需要在别的文件里面使用( mapGetters、mapActions 接下来会说 )时,里面的方法需要注明来自哪一个模块的方法:
//collection.jsconst state = {collects: [], //初始化一个collects数组}const getters = {renderCollects (state) {//承载变化的collectsreturn state.collects}}const mutations = {pushCollects (state,items) {//如何变化collects 插入itemsstate.collects.push(items)}}const actions = {involePushItems (context,item) {//触发mutations里面的pushCollects,传入数据形参item 对应到itemscontext.commit('pushCollects',item)}}export default {namespaced: true,// 用于在全局引用此文件里的方法时标识这一个的文件名state,getters,mutations,actions}//footerStatus.jsconst state = {// 要设置的全局访问的state对象showFooter: true,changableNum: 0//要设置初始的属性值}const getters = {isShow (state) {return state.showFooter},getChangedNum () {return state.changableNum}}const mutations = {show (state) {// 自定义改变state初始值的方法,这里面的参数除了state之外可以再传额外的参数(变量或对象);state.showFooter = true},hide (state) {// 同上state.showFooter = false},newNum (state, num) {state.changableNum+= num}}const actions = {hideFooter (context) {//自定义触发mutations里函数的方法,context于store实例具有相同方法和属性context.commit('hide')},showFooter (context) {//同上context.commit('show')},getNewNum (context, num) {//同上 num为变化的形参context.commit('newNum', num)}}export default {namespaced: true,//用于在全局引用此文中的方法时标识这一个的文件名state,getters,mutations,actions}这样一改就有了关于两个模块的state管理文件了 footerStatus.js和collection.js,现在你要运行当前的代码话,项目会报错!因为我们把上面的代码模块化分开了引用的地方还没有改。接下来咱们一起来看看 mapState,mapGetters,mapActions的使用,首先 在需要用的 组件里面先导入 import {mapState,mapGetters,mapActions} from 'vuex';咱们先修正一下隐藏或显示页面底部的tabs选项卡(就是上面举的临时例子)的组件代码
<template><div id="app"><router-view /><FooterBar v-if="isShow" /></div></template><script>import{ mapState, mapGetters, mapActions } from 'vuex'import FooterBar from '@/components/common/FooterBar'import config from './config/index'export default {name: 'App',components: {FooterBar: FooterBar},data () {return {}},computed:{...mapState({//这里的...是超引用,ES6的语法,意思是state里有多少属性值我可以在这里放多少属性值isShow:state=>state.footerStatus.showFooter //注意这些与上面的区别就是state.footerStatus,//里面定义的showFooter是指footerStatus.js里state的showFooter}),//你也可以用下面的mapGetters来获取isShow的值,貌似下面的更简洁/*...mapGetters('footerStatus',{ //footerStatus指的是modules文件夹下的footerStatus.js模块isShow:'isShow' //第一个isShow是我自定义的只要对应template里v-if="isShow"就行,//第二个isShow是对应的footerStatus.js里的getters里的isShow})*/},watch: {$route(to,from){if(to.name=='book'||to.name=='my'){this.$store.dispatch('footerStatus/showFooter') //这里改为'footerStatus/showFooter',//意思是指footerStatus.js里actions里的showFooter方法}else{this.$store.dispatch('footerStatus/hideFooter') //同上注释}}}}</script>现在项目代码应该就不会报错了,好,最后咱们再来看一下mapActions的用法,实际上上面的this.$store.dispatch('footerStatus/showFooter')已经算是一种执行相应模块的action里的方法了,但有时会牵扯的事件的触发及传值,那就会有下面的mapActions用法了,还记得上面的另一个模块collection.js吗?来看一下里面的actions中的方法结构:
const state={collects:[], //初始化一个colects数组};const getters={renderCollects(state){ //承载变化的collectsreturn state.collects;}};const mutations={pushCollects(state,items){ //如何变化collects,插入itemsstate.collects.push(items)}};const actions={invokePushItems(context,item){ //触发mutations里面的pushCollects ,传入数据形参item 对应到itemscontext.commit('pushCollects',item);}};需要传值来实时变动state.collects里的数据,那肯定要在执行它的地方进行传值了,所以下面用到它的地方我们用了个@click来执行这个invokePushItems方法了,并且传入相应的对象数据item,如下:<template><div ><section class="joinState"><div class="joinStateHead"><span class="h3">全国改性料通讯录</span><span class="joinStatus" @click="invokePushItems(item)">加入收藏列</span></div></section></div></template><script>import { mapActions } from 'vuex'export default {components:{conditionFilter},name: 'bookDetail',data () {return {msg: '',item:{id:'01',productName: '苹果',price:'1.6元/斤'}}},mounted() {this.$store.dispatch('footerStatus/hideFooter')},methods:{...mapActions('collection',[ //collection是指modules文件夹下的collection.js'invokePushItems' //collection.js文件中的actions里的方法,在上面的@click中执行并传入实参])}}</script>这样一来,在这个组件里面操作的 collecttion.js 中的state的数据,在其他的任何的一个组件里面都会得到相应的更新变化了,获取状态的页面代码如下:
<template><div><ul><li v-for="(val,index) in arrList" :key="index"><h5>{{val.productName}}</h5><p>{{val.price}}</p></li></ul></div></template><script>import {mapState,mapGetters,mapActions} from 'vuex';export default {name: 'book',data() {return {}},computed:{// ...mapState({ //用mapState来获取collection.js里面的state的属性值// arrList:state=>state.collection.collects// }),...mapGetters('collection',{ //用mapGetters来获取collection.js里面的gettersarrList:'renderCollects'})}}</script>至此,vuex中的常用的一些知识点使用算是简单的分享完了,当然了,相信这些只是一些皮毛!只能说是给予刚接触vuex的初学者一个参考与了解吧!有哪里不明白的或不对的,留言下。