目录
-
什么是vuex
- vuex是一个专为vue.js应用程序开发的状态管理模式
- 采用集中式存储管理数据,以相应的规则保证状态以一种可预测的方式发生变化
- 简单描述就是状态管理模式(白话: '全局'统一集中式管理全局变量)
-
为何学习vuex
- 程序页面较多时,数据变量也多
- 常用于组件通信(简单的父子通信和兄弟通信我们可以通过props或$emit传值)
-
而复杂的通信我们不可能一步一步将数据传过去,而这个时候就可以通过vuex进行统一数据管理
-
veux的不同组件数据保持同步
-
数据的修改是可追踪的
-
例如:
一个户外商店有两名员工,张三和李四
一天的早上,他们分别对帐篷的数量做了一次盘点,发现一共有三个帐篷
张三卖出去俩个,他以为库存里还有一个
李四卖出去一个,他以为库存里还有两个
而事实上是,库存现在已经为零
如果他们再接受客户的预订,就会出现库存不足的情况
-
张三和李四因为没有保持库存的数量的同步导致了尴尬,这就是所谓的
数据保持同步
-
店长需要知道, 谁卖出了多少个帐篷,这个行为我们称之为
数据修改是可追踪的
-
图示
-
-
安装vuex
-
// 1. 下载vuex: 终端命令(yarn add vuex) // 2. 引入vuex import Vue from 'vue' import Vuex from 'vuex' // 3. 注册(添加Vue.prototype.$store属性) Vue.use(Vuex) // 4. 实例化store对象 const store = new Vuex.Store({}) // 5. 导出store对象取main.js注入给new Vue export default store // 6. 注入到new Vue中(Vue.prototype.$store = store) 确保整个项目有用this.$store
-
vuex基本配置
- vuex配置项是固定,每个配置项有不同的作用,配置项如下图
- 单一定义的store对象,里面有五个配置项,在任意组件都可以使用
-
vuex-state 数据源
- state是唯一的公共数据源(唯一定义变量的地方),统一配置
- state是响应的,只要state值变化,页面上使用的地方会自动更新同步
- 基本语法
-
const store = new Vuex.Store({ state: { 变量名: 初始值 } })
-
state在组件内的使用方式
-
方式一:直接使用
-
this.$store.state.变量名
- 方式二:映射使用(推荐)
-
// 1. 拿到mapState辅助函数 import { mapState } from 'vuex' export default { computed: { // 2. 把state里变量映射到计算属性中 ...mapState(['state里的变量名']) } } // 映射state到计算属性 // 1. 拿到辅助函数 mapState // 2. 在computed内, ...mapState(['state变量名']) // 3. 当计算属性使用
-
-
vuex-mutation 同步修改
- mutation类似于数据管家,操作state里的数据
- mutations里第一个形参是state
- mutation是唯一能修改state的地方,确保调试工具可以追踪变化
- mutations函数上, 只能接收一个参数值, 如果传对个, 请传一个对象
- mutation函数内,只能写同步代码.调试工具可追踪变化的过程
- 因为调试工具要立刻产生一次记录,所以必须是同步的
- 基础语法
-
const store = new Vuex.Store({ mutations: { 函数名 (state, 可选值) { // 同步修改state值代码 } } })
- mutation在组件内的使用方式
- 方式一 : 直接使用
-
this.$store.commit("mutations里的函数名", 具体值)
-
方式二 : 映射使用
-
// 1. 拿到mapMutations辅助函数 import { mapMutations } from 'vuex' export default { methods: { // 2. 把mutations里方法映射到原地 ...mapMutations(['mutations里的函数名']) } } 映射mutations到方法里 // 1. 拿到辅助函数 mapMutations // 2. 在methods内, ...mapMutations(['mutations函数名']) // 3. 当普通方法使用
- state,mutation,时间组图,三者关系图
-
vuex-actions 异步修改
- actions里面放异步操作,mutations里同步修改
- actions不建议直接操作state,因为这样修改,调试工具不可追踪
- 要使用commit给mutations修改state的数据,这样在调试工具是可追踪的
- actions的第一个形参是store
- 基础语法
-
const store = new Vuex.Store({ actions: { 函数名 (store, 可选值) { // 异步代码, 把结果commit给mutations给state赋值 } } })
-
- 组件内使用actions的2种方式
- 方式1; 组件内直接使用
-
this.$store.dispatch('actions函数名', 具体值)
- 方式2: 组件内映射使用
-
// 1. 拿到mapActions辅助函数 import { mapActions } from 'vuex' export default { methods: { // 2. 把actions里方法映射到原地 ...mapActions(['actions里的函数名']) } } 映射actions到方法里 // 1. 拿到辅助函数 mapActions // 2. 在methods内, ...mapActions(['actions函数名']) // 3. 当普通方法使用
- 视图组件,state,mutations,actions的关系
-
vuex-getters 计算属性
- vuex身上的全局状态-计算属性,类似于computed
- getters依赖于state中原始数据的变化,并返回计算后的新数据
- 基础语法
-
const store = new Vuex.Store({ getters: { 计算属性名 (state) { return 值给计算属性 } } })
- 使用getters的2种方式
- 方式1: 组件内直接使用
-
this.$store.getters.计算属性名
- 方式2: 组件内映射使用
-
// 1. 拿到mapGetters辅助函数 import { mapGetters } from 'vuex' export default { computed: { // 2. 把getters里属性映射到原地 ...mapGetters(['getters里的计算属性名']) } }
-
vuex-modules 分模块
-
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象.
-
当应用变得非常复杂时候,store对象就有可能变得相对臃肿,
-
为了解决这个问题,vuex允许我们将store分割成模块(module).
-
每个模块都拥有自己的state,mutation,action,getter,甚至是嵌套子模块
-
模块的基本使用
-
import Vue from 'vue' import Vuex from 'vuex' // 引入的一个分组件 import cartModule from './modules/cart' // 引入的另一个分组件 import userModule from './modules/user' Vue.use(Vuex) const store = new Vuex.Store({ // 模块--- modules: { // 第一个组件的使用 user: userModule, // 第二个组件的使用 cart: cartModule } }) export default store
-
分模块带来的影响
-
只要分模块,state取值方式改变,其他配置暂时不变
-
分模块后,state使用方式改变
-
- state使用方式修改
- 方式1:组件内直接使用
-
原语法: this.$store.state.变量名 分模块后语法: this.$store.state.模块名.变量名
- 方式2: 组件内映射使用
-
原语法: ...mapState(['state里变量名']) ...mapState({'变量名': "state里变量名"}) 分模块后语法: ...mapState({ '变量名': state => state.模块名.变量名 })
-
-
命名空间
- 命名空间是建立在分模块之后产生的
- 不同的命名空间,控制mutations/actions/getters的名字可能会出现相同的
- 为了区分不同模块之间命名冲突
- 开启命名空间语法
-
const moduleShopCar = { // 开启命名空间 - true开-默认false namespaced: true, state () {}, mutations: {}, actions: {}, getters: {}, modules: {} }
- 开启命名空间带来的影响
- state/mutations/actions/getters/的使用方式发生了改变
- state使用方式
- 方式1 : 直接使用
-
开启命名空间之前 this.$store.state.变量名 开启命名空间之后 this.$store.state.模块名.变量名
- 方式2 : 映射使用
-
开启命名空间之前 ...mapState(['state变量名']) 开启命名空间之后 ...mapState("模块名", ['state变量名'])
- mutations使用方式
- 方式1 : 直接使用
-
开启命名空间之前 this.$store.commit("mutations里的函数名", 具体值) 开启命名空间之后 this.$store.commit("模块名/mutations里的函数名", 具体值)
- 方式2 : 映射使用
-
开启命名空间之前 ...mapMutations(['mutations里方法名']) 开启命名空间之后 ...mapMutations("模块名", ['mutations里方法名'])
- actions使用方式
- 方式1 : 直接使用
-
开启命名空间之前 this.$store.dispatch("actions里的函数名", 具体值) 开启命名空间之后 this.$store.dispatch("模块名/actions里的函数名", 具体值)
- 方式2 : 映射使用
-
开启命名空间之前 ...mapActions(['actions里方法名']) 开启命名空间之后 ...mapActions("模块名", ['actions里方法名'])
- getters使用方式
- 方式1 : 直接使用
-
开启命名空间之前 this.$store.getters.计算属性名 开启命名空间之后 this.$store.getters['模块名/计算属性名']
- 方式2 : 映射使用
-
开启命名空间之前 ...mapGetters(['getters里计算属性名']) 开启命名空间之后 ...mapGetters("模块名", ['getters里计算属性名'])
-
一图知所有方法
-