Vuex
1.概念
在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
2.何时使用?
多个组件需要共享数据时
3.工作原理图
4.搭建 vuex 环境
创建文件:
src/store/index.js
//引入Vue核心库 import Vue from "vue"; //引入Vuex import Vuex from "vuex"; //应用Vuex插件 Vue.use(Vuex); //准备actions对象——响应组件中用户的动作 const actions = {}; //准备mutations对象——修改state中的数据 const mutations = {}; //准备state对象——保存具体的数据 const state = {}; //创建并暴露store export default new Vuex.Store({ actions, mutations, state, });
在
main.js
中创建 vm 时传入store
配置项//引入store import store from "./store"; //创建vm new Vue({ el: "#app", render: (h) => h(App), store, });
5.基本使用
初始化数据、配置
actions
、配置mutations
,操作文件store.js
//引入Vue核心库 import Vue from "vue"; //引入Vuex import Vuex from "vuex"; //引用Vuex Vue.use(Vuex); const actions = { //响应组件中的dispatch,传入的第一个参数context有commit,state,dispatch等属性 jia(context, value) { context.commit("JIA", value); }, }; const mutations = { //执行mutate,改变state中的状态 JIA(state, value) { state.sum += value; }, }; //初始化数据 const state = { sum: 0, }; //创建并暴露store export default new Vuex.Store({ actions, mutations, state, });
组件中读取 vuex 中的数据:
this.$store.state.sum
组件中修改 vuex 中的数据:
this.$store.dispatch('action中的方法名',数据)
或this.$store.commit('mutations中的方法名',数据)
备注:若没有网络请求或其他业务逻辑,组件中也可以直接 commit,即不写
dispatch
,直接写commit
6.getters 的使用
概念:当 state 中的数据需要经过加工后再使用时,可以使用 getters 加工。
在
store.js
中追加getters
配置const getters = { // bigSum 可以理解为一个计算属性 bigSum(state){ return state.sum * 10 } } //创建并暴露store export default new Vuex.Store({ ...... getters })
组件中读取 getters 中的数据:
this.$store.getters.bigSum
7.四个 map 方法的使用
为什么要使用 mapXXX 方法?
当我们在组件中操作 store 中存储的数据时不可避免的要编写大量的 computed 和 methods,这样的操作十分繁琐,而使用 mapXXX 方法能简化我们的操作。例如借助mapState()
方法可以帮我们生成相应的 computed,借助mapActions()
方法可以帮我们生成相应的 methods,其他的方法同理。再使用 … 扩展运算符将生成的 computed 或 methods 展开。首先需要在组件中导入 mapXXX 方法
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
mapState 方法:用于帮助我们映射
state
中的数据为计算属性computed: { //(对象写法)借助mapState生成计算属性:sum、school、subject ...mapState({sum:'sum',school:'school',subject:'subject'}), //(数组写法)借助mapState生成与state中的数据同名的计算属性:sum、school、subject ...mapState(['sum','school','subject']), },
mapGetters 方法:用于帮助我们映射
getters
中的数据为计算属性computed: { //(对象写法)借助mapGetters生成计算属性:bigSum ...mapGetters({bigSum:'bigSum'}), //(数组写法)借助mapGetters生成同名的计算属性:bigSum ...mapGetters(['bigSum']) },
mapActions 方法:用于帮助我们生成与
actions
对话的方法,即:包含$store.dispatch(xxx)
的函数methods:{ //(对象写法)靠mapActions生成:incrementOdd、incrementWait ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}) //(数组写法)靠mapActions生成同名的:jiaOdd, jiaWait ...mapActions(['jiaOdd','jiaWait']) }
mapMutations 方法:用于帮助我们生成与
mutations
对话的方法,即:包含$store.commit(xxx)
的函数methods:{ //(对象写法)靠mapActions生成:increment、decrement ...mapMutations({increment:'JIA',decrement:'JIAN'}), //(数组写法)靠mapMutations生成同名的methods:JIA、JIAN ...mapMutations(['JIA','JIAN']), }
注意:借助 mapActions 与 mapMutations 生成的 methods 需要向 actions 和 mutations 传递参数时,必须要在调用该 method 的时候传递参数。
8.模块化+命名空间
目的:让代码更好维护,让多种数据分类更加明确。
修改
store.js
const countAbout = { namespaced:true,//开启命名空间 state:{x:1}, mutations: { ... }, actions: { ... }, getters: { bigSum(state){ return state.sum * 10 } } } const personAbout = { namespaced:true,//开启命名空间 state:{ ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { countAbout: countAbout, personAbout: personAbout } })
开启命名空间后,组件中读取 state 数据:
//方式一:自己直接读取 this.$store.state.countAbout.sum //方式二:借助mapState生成后再读取: ...mapState('countAbout',['sum','school','subject'])
开启命名空间后,组件中读取 getters 数据:
//方式一:自己直接读取 this.$store.getters['countAbout/bigSum'] //方式二:借助mapGetters生成后再读取: ...mapGetters('countAbout',['bigSum'])
开启命名空间后,组件中调用 dispatch
//方式一:自己直接dispatch this.$store.dispatch('personAbout/addPersonWang',person) //方式二:借助mapActions生成后再读取: ...mapActions('personAbout',['addPersonWang'])
开启命名空间后,组件中调用 commit
//方式一:自己直接commit this.$store.commit('personAbout/ADD_PERSON',person) //方式二:借助mapMutations生成后再读取: ...mapMutations('personAbout',['ADD_PERSON'])
本文章根据尚硅谷笔记整理而成