前言
在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新建文件夹和文件
左侧红框内的目录结构, store/actions、store/mutations为根actions和mutations定义的文件 store/moudles/* 每个module定义的文件
- 定义根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核心原理解析。
总结
在大型到vue项目中vuex基本上是必不可少到插件之一,它被众多开发者青睐到原因有以下两点:一 vue原生到对于兄弟组件,以及多级组件间的传递值在开发时很容易出错。二 如果使用vue原生的值传递对于项目的维护是很复杂的。总的来说就是可维护性低,开发复杂度高。有了vuex就可以完美的避免这两点,当然这只是对于组件较多嵌套层次深的项目而言。本节主要介绍了vuex的使用下节将与大家一起分析下vuex的相关源码。