1. 概念
在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
2. 何时使用
多个组件需要共享数据时
3. 搭建Vuex环境
- 创建文件:src/store/index.js
import Vue from 'vue' import Vuex from 'vuex' //应用插件 Vue.use(Vuex) //准备state对象 -- 保存具体数据 const state = {} //准备mutations对象 -- 修改state中的数据 (直接操作数据,做些简单的增删改查) const mutations= {} //准备actions对象 -- 相应组件中用户的动作 // (进行逻辑处理,然后通过commit执行mutations里的方法) const actions = {} export default new Vuex.Store({ state, mutations, actions })
- 在main.js 中创建vm时传入store配置项
...... //引入store import store from './store' ...... //创建vm new Vue({ el: '#app', render: h => h(App) store: store })
4.基本使用
- 初始化数据,配置 actions ; mutations ,操作文件store.js
import Vue from 'vue' import Vuex from 'vuex' //应用插件 Vue.use(Vuex) //准备state对象 -- 保存具体数据 const state = { count: 0 } //准备mutations对象 -- 修改state中的数据 (直接操作数据,做些简单的增删改查) const mutations= { increment (state,value) { state.count += value } } //准备actions对象 -- 相应组件中用户的动作 // (进行逻辑处理,然后通过commit执行mutations里的方法) const actions = { add(context,value) { //context.commit('increment',value) context.commit('INCREMENT',value) } } export default new Vuex.Store({ state, mutations, actions })
- 组件中读取vuex中的数据:$store.state.count(模板中 ) 或 this.$store.state.count(js中)
- 组件中修改vuex中的数据:$store.dispatch('actions中的方法',数据) 或 $store.commit('mutations中的方法',数据)
备注:若没有网络请求或者其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接使用commit
5.getters的使用
- 概念: 当state中的数据需要经过加工后再使用时,可以使用getters加工
- 在 store.js 中追加 getters 配置
...... const getters= { bigNumber(state) { return state.count * 10 } } export default new Vuex.Store({ ...... getters })
- 组件中读取数据:$store.getters.bigNumber(模板中 ) 或 this.$store.getters.bigNumber(js中)
6.四个map方法的使用
- mapState方法:用于帮助我们映射 state 中的数据为计算属性
// 在单独构建的版本中辅助函数为 Vuex.mapState import { mapState } from 'vuex' export default { // ... computed: { //对象写法 ...mapState({ count: 'count', ...... }) //数组写法 ...mapState(['count', ......]) } }
- mapGetters方法:用于帮助我们映射 getters 中的数据为计算属性
import { mapGetters } from 'vuex' export default { computed: { // 使用对象展开运算符将 getter 混入 computed 对象中 // 数组写法 ...mapGetters(['bigNumber', ......]), //对象写法 ...mapGetters({bigNumber: bigNumber, ......}) } }
- mapActions方法:用于帮助我们生成与 actions 对话的方法,即包含 $store.dispatch(xxx)的函数
import { mapActions } from 'vuex' export default { // ... methods: { // 数组写法 ...mapActions(['add', ...... ]), // 对象写法 ...mapActions({addNumber : 'add', ...... }) } }
- mapMutations方法:用于帮助我们生成与 mutations 对话的方法,即包含 $store.commit(xxx)的函数
import { mapMutations } from 'vuex' export default { methods: { // 数组写法 ...mapMutations([ 'increment', ...... ]), // 对象写法 ...mapMutations({ add: 'increment', ...... }) } }
备注:mapActions与mapMutations使用时,若需要传递参数,需要在模板中绑定事件时传递好参数,否则参数就是事件对象
7.模块化 + 命名空间
- 目的:让代码更好维护,让多种数据分类更加明确
- 修改 store.js
const moduleA = { namespaced: true, state: () => ({ count: 0 }), mutations: { increment (state) { // 这里的 `state` 对象是模块的局部状态 state.count++ } }, actions: { incrementIfOddOnRootSum ({ state, commit, rootState }) { if ((state.count + rootState.count) % 2 === 1) { commit('increment') } } }, getters: { doubleCount (state) { return state.count * 2 } } } const moduleB = { state: () => ({ ... }), mutations: { ... }, actions: { ... }, getters: { sumWithRootCount (state, getters, rootState) { return state.count + rootState.count } } } const store = new Vuex.Store({ modules: { moduleA, moduleB } })
- 开启命名空间后,组件中读取state数据:
//方式一,自己直接读取 this.$store.state.moduleA.count //方式二,借助 mapState 读取 ...mapState('moduleA',['count'])
- 开启命名空间后,组件中读取getters数据:
//方式一,自己直接读取 this.$store.getters['moduleA/doubleCount'] //方式二,借助 mapGetters 读取 ...mapGetters('moduleA',['doubleCount '])
- 开启命名空间后,组件中调用dispatch:
//方式一,自己直接读取 this.$store.dispatch('moduleA/incrementIfOddOnRootSum',参数) //方式二,借助 mapActions 读取 以下二选一 ...mapActions('moduleA',['incrementIfOddOnRootSum']) ...mapActions('moduleA',{incrementOdd:'incrementIfOddOnRoostSum'})
- 开启命名空间后,组件中调用commit:
//方式一,自己直接读取 this.$store.commit('moduleA/increment',参数) //方式二,借助 mapActions 读取 以下二选一 ...mapMutations('moduleA',['increment']) ...mapMutations('moduleA',{add:'increment'})