1 理解vuex
1.1 vuex是什么?
- 概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信
- Github地址
1.2 什么时候使用Vuex
- 多个组件依赖于同一状态
- 来自不同组件的行为需要变更为同一状态
1.3 与事件总线共享及更新数据相比较
1.3.1 全局事件总线共享及更新数据示意图
A组件中有数据x,y,若有其他组件BCD都需要使用并修改A组件中的x数据的时候,若用全局事件总线的方式实现起来,组件少的话就挺方便的,但组件一多起来就会很麻烦,这时候就需要用到Vuex了。
1.3.1 Vuex共享及更新数据示意图
1.4 vuex的工作原理图
vuex的原理与去餐厅吃饭流程类似
- Vue Components:组件,相当于餐厅中的客人
- Action:相当于餐厅中的服务员,在vuex中是用于响应组件中的动作的对象,可与后端接口交互,一般只在需要通过ajax向后端请求数据的时候调用,若无请求数据要求,则可直接将数据和处理逻辑Commit给Mutations,所以在原理图中,组件与Commit之间应该在画 一条线。
- Mutations:相当于餐厅后厨,用于操作数据的对象,可对数据进行逻辑处理
- State:相当于做好的菜,用于存储数据的对象
2 使用vuex
2.1 搭建vuex环境
-
创建文件
src/store/index.js
// 该文件用于创建vuex中最为核心store // 引入Vue import Vue from 'vue' // 应用Vuex插件 Vue.use(Vuex) // 引入Vuex import Vuex from 'vuex'; // 准备actions——用于响应组件中的动作 const actions = {} // 准备mutations——用于操作数据(state) const mutations = {} // 准备state——用于存储数据 const state = {} // 创建并暴露store export default new Vuex.Store({ actions, mutations, state, })
-
在
main.js
中创建vm时传入store
配置项// 引入Vue import Vue from 'vue' // 引入App import App from './App.vue' // 引入store import store from './store/index'; ...... // 创建VM new Vue({ el: '#app', render: h => h(App), store })
3 基本使用
-
初始化数据、配置
actions
、配置mutation
、操作文件store.js
// 该文件用于创建vuex中最为核心store // 引入Vue import Vue from 'vue' // 应用Vuex插件 Vue.use(Vuex) // 引入Vuex import Vuex from 'vuex'; // 准备actions——用于响应组件中的动作 const actions = { // 响应组件中加的动作 increament(context, data) { context.commit("increament", data) }, } // 准备mutations——用于操作数据(state) const mutations = { // 执行组件中加的动作 increament(state, data) { console.log("mutations中的increament被调用了", state); state.sum += data }, } // 准备state——用于存储数据 const state = { sum: 0, } // 创建并暴露store export default new Vuex.Store({ actions, mutations, state, })
-
组件中读取vuex中的数据:
$store.state.sum
-
组件中修改vuex中的数据:
$store.dispatch('actions中的方法名',数据)
或$store.commit('mutations中的方法名',数据)
**注意:**若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写
dispatch
,直接写commit
4 getters的使用
- 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
- 再
store.js
中追加getters
配置项 - 组件中读取数据:
$store.getters.bigSum
5 四个map方法的使用
-
**mapState方法:**用于帮助我们映射
state
中的数据为计算属性computed:{ //借助mapState生成计算属性,从state中读取数据(对象写法) ...mapState({ sum: 'sum', school: 'school', subject: 'subject' }), //借助mapState生成计算属性,从state中读取数据(数组写法) ...mapState(['sum','school','subject' ]), }
-
**mapGetters方法:**用于帮助我们映射
getters
中的数据为计算属性computed:{ //借助mapGetters生成计算属性,从getters中读取数据(对象写法) ...mapGetters({ bigSum: 'bigSum' }), //借助mapGetters生成计算属性,从getters中读取数据(数组写法) ...mapGetters(['bigSum']), }
-
**mapMutations方法:**用于帮助我们生成与
mutations
对话的方法,即:包含$store.commit(xxx)
的方法methods:{ // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法) ...mapMutations({ increament: 'increament', decreament: "decreament" }), // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法) ...mapMutations(['increament', "decreament"]), }
-
**mapActions方法:**用于帮助我们生成与
actions
对话的方法,即:包含$store.dispatch(xxx)
的方法methods:{ // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法) ...mapActions({ increamentOdd: 'increamentOdd', increamentWait: "increamentWait" }), // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法) ...mapActions(['increamentOdd', "increamentWait"]), }
注意:
- mapActions与mapMutations使用时,若要传递参数,则需要在模板绑定事件时传递好参数,否则参数就是事件对象。
- mapState或mapGetters若要使用对象写法,则要求组件中计算属性名要与vuex中state对象中的属性名或getters对象中函数名保持一致。
- mapMutations或mapActions若要使用对象写法,则要求组件中函数名要与vuex中mutations对象00中的函数名或actions对象中函数名保持一致。
6 模块化+命名空间
-
**目的:**让代码更好维护,让多种数据分类更加明确
-
修改store目录下的
index.js
// 该文件用于创建vuex中最为核心store // 引入Vue import Vue from 'vue' // 引入Vuex import Vuex from 'vuex'; // 应用Vuex插件 Vue.use(Vuex) const personOptions = { namespaced: true,//开启命名空间 actions: {...}, mutations: {...}, state: {...}, getters: { bigSum(state) { return state.sum * 10 } } } const personOptions = { namespaced: true,//开启命名空间 actions: {...}, mutations: {...}, state: {...}, getters: {...} } // 创建并暴露store export default new Vuex.Store({ modules: { countOptions, personOptions } })
-
开启命名空间后,组件中读取state数据:
//方式一:自己直接读取: this.$store.state.personOptions.personList //方式二:借助mapState读取: ...mapState('countOptions',['sum','school','subject']),
-
开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取: this.$store.getters[personOptions/firstPersonName] //方式二:借助mapState读取: ...mapGetters('countOptions',['bigSum']),
-
开启命名空间后,组件中调用dispatch:
//方式一:自己直接调用dispatch: this.$store.dispatch('personOptions/addPersonWang'.person) //方式二:借助mapActions读取: ...mapActions('countOptions',['increamentOdd', "increamentWait"]),
-
开启命名空间后,组件中调用commit:
//方式一:自己直接读取: this.$store.commit(personOptions/add,person) //方式二:借助mapState读取: ...mapMutations('countOptions',['increament', "decreament"]),