文章目录
1. vuex 是什么
- 专门在 Vue 中实现集中式状态数据管理的一个 Vue 插件
- 对 Vue 应用中多个组件共享状态进行集中式的管理(读写)
- 也是一种组件间的通信方式,且适用于任意组件间通信
- 说白了就是多个组件用到了共同的数据,可以放在 vuex 中去管理
2. 什么时候使用 vuex
- 多个组件依赖于同一状态
- 多个组件所依赖的数据都是相互影响的,组件 A 中共享数据的更改,组件 B 中共享的同一数据默认也会改
3. vuex 工作原理
官方图
4. vuex 安装与搭建
-
现在如果使用 npm 安装 vuex 默认为
Vuex4
,Vuex4
适配Vue3
,Vuex3
适配Vue2
npm i vuex@3
-
创建
store/index.js
文件import Vue from "vue" import Vuex from "vuex" // 在实例化前,必须使用该插件 Vue.use(Vuex) // 导出该对象 export default new Vuex.Store({ // 状态、数据 state: { }, // 获取、计算属性 getters: { }, // 逻辑处理 mutations: { }, // 异步请求、异步处理 actions: { } })
import Vue from 'vue' import App from './App.vue' // 主文件中导入并挂载 import store from "./store/index" // 取消生成生产提示 Vue.config.productionTip = false new Vue({ render: h => h(App), // 挂载 vuex store, }).$mount('#app') // 挂载之后全局会多一个 $store 属性
5. vuex 核心概念和 API
5.1 state
-
用于状态管理,它里面的数据所有组件都可以访问,并且也是共享的
-
类似于组件中的 data,数据也是响应式的
-
组件获取:
this.$store.state.xxx
state: { // 数据 num: 2 }
5.2 getters
-
对 state 中的数据进行加工处理
-
类似于组件中的 computed
-
组件获取:
this.$store.getters.xxx
getters: { getNum(state, getters){ // state:数据 // getters:自己 return state.num * 10 } },
5.3 mutations
-
该方法用于逻辑处理,可以直接操作 state
-
类似于组件中的 methods
-
需要 commit(“方法名”),去触发 mutations 中的方法
mutations: { add(state, value) { // state:数据 // value:传入的数据 state.num += value } },
5.4 actions
-
可以处理一些异步的数据
-
在 actions 中可以直接修改 state 中的值,但是官网并没有这样去建议
-
需要 dispatch(“方法名”),去触发 mutations 中的方法
actions: { add(store, value) { // store:一个不完整的 store // value:传入的数据 // 提交任务到 mutations 中 store.commit("add", value) } }
上面的解释可能不太清除:
- 首先在组件中的 vuex 都需要用 $store 去获取,这个是 vue 内部实现的
- 一个基本流程是
- 在组件中调用 this.$store.dispatch(‘方法名’, 传入数据)
- actions 中的方法被触发了,然后调用 store.commit(“方法名”, 传入数据)
- mutations 中的方法被触发了,然后就可以直接去修改 state 了
- 由于 state 中的数据是响应式的,数据发生了改变默认会再次渲染视图
- 如果没有异步操作的话,其实也可以不用调用 actions 中的方法,这样可以节省一步操作
5.5 Module
-
当数据量太大的时候可以使用 Module 进行模块化管理
-
每一个模块中都有上面四个属性
// 下面是官网的一个例子 const moduleA = { state: () => ({ ... }), getters: { ... }, mutations: { ... }, actions: { ... }, } const moduleB = { state: () => ({ ... }), getters: { ... }, mutations: { ... }, actions: { ... } } export default new Vuex.Store({ modules: { a: moduleA, b: moduleB } })
6. 辅助函数
6.1 mapState与mapGetters
-
mapState:在组件中使用数据的时候要通过 this.$store.state.xxx 去获取,这样数据量多了的话,就特别的重复和冗余
-
当然也可以使用计算属性
// 其实这样也不太好,数据量多的话还是会写很多的东西 computed: { xxx() { return this.$store.state.xxx } }
-
vuex 中提供了辅助函数,可以帮助我们生成计算属性
// mapState 函数返回的是一个对象,对象中把你传入的对象变成了函数 computed: { ...mapState ({ // value:就相等于 this.$store.state.xxx // key:这样就可以直接通过 key 去使用了 // 说白了 value 是 vuex 的,key 是组件的 key: "value", key1: "value1", key2: "value2" }) } // 比如这里返回的对象就是下面这样的,所以可以通过展开运算符,去添加到计算属性中 { key() { }, key1() { }, key2() { } }
-
当映射的 key 和 value 相同时
// 也可以使用数组去展开,效果和对象一样的 computed: { ...mapState (["num","num1","num2"]) } // 这种写法就相当于,你之前要用 this.$store.state.num 去获取数据 // 但是现在只需要用 num 去获取数据
-
mapGetters:和 mapState 的用法是一模一样的
6.2 mapMutations与mapActions
-
mapMutations:自动帮忙调用 commit
methods: { // 正常触发 mutations 中的方法 vcApi(){ this.$store.commit("vuexApi", 传入数据) } // 辅助函数,这种写法需要在调用 vcApi 这个方法的时候传入数据 ...mapMutations({ vcApi: "vuexApi" }) } // 数组写法 methods: { // 这种方式需要组件方法名和 mutations 中的方法名一致 ...mapMutations(["Api"]) }
-
mapActions:自动帮忙调用 dispatch,和 mutations 使用一样
7. 模块化编码与命名空间
-
Module 文件
const moduleA = { // 默认情况下这些属性都还是全局的,开启命名空间后变为模块的 // 开启命名空间,这里面的属性和方法,需要用当前名字的前缀才能获取 namespaced: true, state: () => ({ ... }), getters: { ... }, mutations: { ... }, actions: { ... }, } export default new Vuex.Store({ modules: { moduleA } })
-
直接获取/使用
this.$store.moduleA.state.xxx this.$store.getters['moduleA/xxx'] this.$store.commit('moduleA/xxx', 传入数据) this.$store.dispatch('moduleA/xxx', 传入数据)
-
辅助函数获取/使用
computed: { ...mapState("moduleA", {key: "value1"}), ...mapGetters("moduleA", ["num1", "num2"]) } methods: { ...mapMutations("moduleA", {vcApi: "vuexApi"}), ...mapActions("moduleA", ["Api"]) }