vue之vuex详细配置和使用
该文章描述的是利用脚手架自动搭建的vuex目录结构,再加上自己的进一步封装而写成的。
vuex是vue全家桶自带的一个模块,在根目录的store/index.js中进行配置,在main.js中使用
import store from "./store"
*(默认选中index.js文件)导入即可
-
store/index.js中的配置(默认)
import Vue from 'vue'; import Vuex from 'vuex'; //挂载vuex Vue.use(Vuex); //创建store实例 const store = new Vuex.Store({ state:{}, //相当于一个存储空间 getters:{}, //state的计算数据 实现数据过滤的作用(get) mutations:{},//设置state中的数据(set) actions:{}, //可以发送异步请求 modules:{}, //拆分存储空间模块化 plugins:{}, //拓展vuex功能 }) //导出store对象 export default store;
-
进一步封装(拆分创建store实例时的配置项)
-
目录树
+ store + index.js + state.js + getters.js + mutations.js + actions.js + modules + user.js + plugins // 这个配置文件是为了实现vuex的数据持久化 + saveInLocal.js
-
index.js中代码编写
import Vue from 'vue'; import Vuex from 'vuex'; import state from './state'; import getters from './getters'; import mutations from './mutations'; import actions from './actions'; import m_user from './modules/user.js' import saveInLocal from './plugins/saveInLocal' Vue.use(Vuex); /* 这里涉及一个代码风格的设计思想,将目录名称与要设置的对象名称命名为一样的名称,可以利用es6语法,实现快速导入。 */ const store = new Vuex.Store({ state, //也就是 state:state getters, mutations, actions modules:{ m_user }, plugins:[saveInLocal] }) export default store;
-
state.js中代码编写
export default { code:"qq", name:"张三" }
-
getters.js中代码编写
export default { _getName:(state)=>{ return "这是通过getters添加的"+state.name; }, _getInfo:(state)=>{ return `${state.name}-${state.code}`; } }
-
mutations.js中代码编写
mutations中不能有异步方法
export default { SET_NAME:(state,param)=>{ state.name = param } }
-
actions.js中代码编写
axtions执行逻辑:actions->mutations->state->视图
//封装一下定时器promise function delay(time){ return new Promise((resolve,reject)=>{ //起定时器 setTimeout(resolve,time) }) } export default { //5s后修改名字 /* setNameAfter5:(store,param)=>{ setTimeout({ this.store.commit('SET_NAME',param) },5000) } */ //上面那种普通的办法太过繁琐,使用promise封装 /* setNameAfter5:(store,param)=>{ delay(5000).then(()=>{ this.store.commit('SET_TIME',param) }) } */ //这个还是有点麻烦,使用promise的async和await修饰词 /* setNameAfter5:async (store,param)=>{ await delay(5000); this.store.commit('SET_TIME',param) } */ //上面的改变还是不够精简,利用es6语法(解构赋值、函数简写) async setNameAfter5({commit},param){ await delay(5000); commit('SET_TIME',param) } //NICE~ }
-
modules/user.js中代码编写
//封装定时器 function delay(time){ return new Promise((resolve,reject)=>{ setTimeout(resolve,time) }) } export default { state:{ userName:"李四" }, getters:{ getUserName:(state)=>{ return "我是" + state.userName; } }, mutations:{ SET_NAME:(state,param)=>{ return state.userName = "hahah" } }, actions:{ async setUsernameAfter5({commit},param){ await delay(5000); commit('SET_NAME',param); } } }
-
-
-
vue页面中对state中存储内容的读取(state,getters)操作(computed)
<template> <!--state 的 computed调用--> {{ getName }} <!--getters 的 computed调用--> {{ _getName }} <!--子模块的state的computed调用--> {{userName}} <!--子模块的getters的computed调用--> {{getUserName}} </template> <script> import { mapState,mapGetters } from 'vuex' //使用vuex自带的方法 export default{ //state中存储的值需要在computed中获取 //getters中的函数也只能在computed中调用 computed:{ //state******* //方法三:这种方法是可以在return前做一个数据处理 ...mapState({ getName:(state)=>{ //做个数据处理再返回 return state.name + '哈哈哈哈' }, code:(state)=>state.code }), //方法二:mapState(需要获取state存储空间中值的数组列表),它的返回值是一个函数数组,而computed就需要一个个函数,所以在此将返回的数组展开即可 ...mapState(['name']),//同样能拿到name的值 getName(){ //方法一:使用默认方法拿取name值 let name = this.$store.state.name; return name; }, //getters******* //方法一:使用默认方法调用getName _getName(){ return this.$store.getters._getName; }, //方法二:使用vuex的map方法 ...mapGetters(['_getInfo','_getName']), //方法三:使用对象(但getters本身就是计算后属性,这个方法一般不使用) ...mapGetters({ _getInfo:(state)=>{//做数据处理} }), /***********子模块***********/ //state****** userName(){ //方法一:使用默认方法拿取username值 this.$store.state.m_user.userName; }, //方法二:通过mapState ...mapState('m_user',['userName']) //方法三:对象 ...mapState('m_user',{ userName:(state)=>{ return state.userName + '可以进行修改' } }), //getters****** getUserName(){ //方法一:使用默认方法 return this.$store.getters['m_user/getUserName'] } //方法二:使用mapGetters ...mapGetters('m_user',['getUserName']) } } </script>
-
vue页面对state中存储的值进行修改(mutations\actions)操作(methods)
在严格模式下,不支持直接修改state中的值
//index.js中 const store = new Vuex.Store({ strict : true //严格模式开启 //其它忽略不写 })
页面代码
<template> <view>{{ name }}</view> <view>{{ userName }}</view> <button @click="changeName">修改name值</button> <button @click="changeNameAsync">5s后修改name的值</button> <button @click="changeUsername">修改userName的值</button> <button @click="changeUsernameAsync">5s后修改userName的值</button> </template> <script> import { mapState,mapMutations,mapActions } from 'vuex' export default { computed:{ ...mapState(['name']), //拿到name值 ...mapState('m_user',['userName']) } methods:{ //默认根模块 //mutations(同步修改) ...mapMutation(['_SETNAME']), changeName(){ //方法一:直接通过$store修改(vuex不推荐直接修改) this.$store.state.name = "哈哈哈哈" //方法二:用过mutation进行修改 this._SETNAME('哈哈哈哈'); } //actions(异步修改) ` `...mapActions(['setNameAfter5']), //5s后修改名字 changeNameAsync(){ //方法一:使用默认store的dispatch进行分发 this.$store.dispatch('setNameAfter5',"dispatch") //方法二:通过mapAction进行修改 this.setNameAfter5('名字'); } //子模块m_user ...mapMutations('m_user',['SET_NAME']), //mutations(同步修改) changeUsername(){ //方法一:直接修改 this.$store.state.m_user.userName = "修改啦" //方法二:使用mapMutations this.SET_NAME('修改啦') }, //actions异步修改 ...map('m_user',['setUsernameAfter5']), changeUsernameAsync(){ this.$store.dispatch('setUsernameAfter5','5s后修改') } } } </script>
-
vuex配置项之持久化
saveInLocal.js中代码的编写
function saveInLocal(store){ console.log(store,'初始化state数据') if(localStorage.state){ store.replaceState(JSON.parse(localStorage.state)); } store.subscribe((mutations,state)=>{ console.log('mutation被调用,就执行') // 将state存储到localStorage中 localStorage.state = JSON.stringify(state); }) } export default saveInLocal
-