前言
在vue项目中,如果我们涉及到兄弟组件间的传值(及多个组件共享一个状态)。遇到这种情况使用vuex来解决是目前比较流行的解决方案。虽然在vuex官方文档中详细介绍了vuex的使用方法,但是文档中的内容太过细节,初次阅读不易抓住重点。本篇文章根据自身使用vuex的经验来精简的说明下vuex的使用,希望内能够给初次使用vuex的小伙伴提供些帮助,也希望熟悉这块的道友如发现文章不到之处给出指正。
注:本文介绍两种使用vuex的方式,一种适用于简单并且共享状态较少的情况,一种适用于复杂并且状态较多的情况。
VUEX 基本使用方式
- 新建个store.js文件,main.js中引入并且添加到vue中。(如图1)
- 定义状态和改变状态的mutations
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions:{
setCount: ({ commit }, count) => {
commit('SET_COUNT', count)
},
}
})
export default store
复制代码
- 获取状态值/改变状态值/异步改变状态
let count = this.$store.state.count//获取状态的值
this.$store.commit('increment')//mutations改变状态
this.$store.dispatch('setCount')//actions改变状态(异步执行的)
复制代码
VUEX module使用方式
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿为了解决以上问题,Vuex 允许我们将 store 分割成模块 (module)。每个模块拥有自己的 state、mutation、action、 甚至是嵌套 子模块——从上至下进行同样方式的分割(引用官方文档的一句话):
- 根据所需modules新建文件夹和文件
- 定义根state以及modules的相关属性
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import user from './modules/user'
import mutations from './mutations'
import actions from './actions'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
app,
user
},
//根状态
state: {
menus:[],
},
mutations:mutations,
actions: actions,
})
复制代码
/modules/user.js中的定义。(每个module中都可以定义自己的state mutations actions getters)
const user = {
state:{
userInfo:{}
},
mutations:{
SET_USER_INFO: (state, userInfo) => {
state.userInfo = []
state.userInfo = userInfo
},
},
actions:{},
getters:{},
}
export default user
复制代码
3. 获取状态值/改变状态值/异步改变状态 根目录的state值获取改变以及异步state改变同VUEX 基本使用方式中的使用方式。 module中的state值(store.state.moduleName)获取改变以及异步state改变:
this.$store.state.user.userInfo
this.$store.commit("SET_USER_INFO")
复制代码
当我们定义两个模块中有相同的mutation属性是此时commit会同时改变这两个模块。此时我们应该如何处理呢?
- mutation属性命名是加上模块名前缀如:SET_USER_*(多人开发时必须强制规范),此种方法虽然简单,但如果团队中出现不按规范来的人时就会出现很大问题。
- vuex给出了定义命名空间的解决方法:
const user = {
namespaced: true,//成为带命名空间的模块
state:{
userInfo:{}
},
mutations:{
SET_INFO: (state, userInfo) => {
state.userInfo = []
state.userInfo = userInfo
},
},
actions:{},
getters:{},
}
export default user
复制代码
如果模块namespaced被设置为true name 当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。意思就是此时所有的属性名都会自动改变成 "ModuleName/*"及模块名/属性名 这两种方式,我们项目中使用的是第二种因为这个项目的小伙伴是首次合作,人为控制变量名容易出现问题。
其他
VUEX中为了方便我们开发还提供了辅助函数mapState mapGetters mapActions mapMutations ,如果有兴趣的小伙伴可以去官方文档学习下。另外如果有对vuex源码感兴趣的小伙伴可以去参考下我的另一篇文章vue全家桶之vuex核心原理解析。