vuex的使用
1. 概念
Vuex
是适用于在Vue项目开发时使用的状态管理工具。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
2. Vuex 和单纯的全局对象的不同点
Vuex
的状态存储是响应式的。当Vue
组件从store
中读取状态的时候,若store
中的状态发生变化,那么相应的组件也会相应地得到高效更新。- 不能直接改变
store
中的状态。改变store
中的状态的唯一途径就是显式地提交(commit) mutation
。
3. 适用场景
- 中大型单页应用开发
- 多个视图(组件)共享同一状态。
4. 作用
项目数据状态的集中管理,解决复杂组件(如兄弟组件、非兄弟组件)的数据通信问题。
5. 安装
npm i vuex -s
(指令安装)- 脚手架安装
6. 核心内容(概念)
6.1 State
6.1.1 意义
vuex
中的数据源,我们需要保存的数据(状态)。
6.1.2 增删 state 中的数据
- 增
Vue.set(state,"name","kaka")
- 删
Vue.delete(state,"name")
6.1.3 调用
由于 Vuex
的状态存储是响应式的,从 store
实例中读取状态最简单的方法就是在计算属性(computed
)中返回某个状态,每当状态发生变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM
。
- 直接调用
2. 辅助函数调用
6.2 Getters
6.2.1 意义
Getters
相当于vue中的computed
计算属性,getters
的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算,Getters
可以用于监听state
中的值的变化,返回计算后的结果,说白了就是对state
中的成员加工后传递给外界,使用方法如下:
6.2.2 调用
- 直接调用:
this.$store.getters.xxx
- 辅助函数调用: 上方图例
6.3 Mutations
6.3.1 意义
修改store
中的值唯一的方法就是提交mutation
来修改
6.3.2 普通方法调用
- 直接修改
state
(同步方法)
(1) 在组件的对应方法中通过this.$store.commit('方法名')
来触发mutations
(2)mutations
操作state
中的数据
2. 异步方法
(1) 在组件的对应方法中通过this.$store.dispatch('方法名')
来触发actions
(2) 再通过actions
的commit
来触发mutations
(3) mutations
操作state
中的数据
6.3.2 辅助函数调用
- 同步方法
- 异步方法
6.3.4 Mutations传值
- 提交单个值时
//提交
this.$store.commit("edit",15)
//接收
edit(state,payload){
console.log(payload) // 15
}
- 提交多个值时
//提交
this.$store.commit("edit",{age:18,sex:"女"})
//接收
edit(state,payload){
console.log(payload) // {age:18,sex:"女"}
console.log(payload.age) //18
console.log(payload.sex) //女
}
- 使用辅助函数时的传参
6.4 Actions
由于直接在mutation
方法中进行异步操作,将会引起数据失效。所以提供了Actions
来专门进行异步操作,最终提交mutation
方法。
Action
类似于 mutation
,不同在于:
Action
提交的是mutation
,而不是直接变更状态。Action
可以包含任意异步操作。
6.5 Module
6.5.1 意义
Vuex
允许我们将 store
分割成多个模块(module
)。每个模块拥有自己的 state、mutation、action、getter
、甚至是嵌套子模块。当我们项目中的数据、逻辑较为多的情况下使用module
会使我们的代码变得不那么繁琐。
6.5.2 使用
- 现在在
store
里面建个文件夹,命名为module
,然后再里面新建一个moduleA.js
文件,并编写如下代码:
moduleA.js
的初始内容:
const state = {}
const actions = {}
const mutations = {}
// 最后统一导出
export default {
namespaced: true, //***
state,
actions,
mutations
}
- 然后打开
store
下的index.js
文件,导入这两个module
- 这个时候,
store
中已经注入了两个子模块moduleA moduleB
,我们可以在相应的组件中通过直接调用法或辅助函数调用法访问模块中的state
数据。
模块内部的 action、mutation
和 getter
默认是注册在全局的,这样使得多个模块能够对同一 mutation
或 action
作出响应。
6.5.3 命名空间
前面我们已经知道了,模块内部的 action、mutation
和 getter
默认是注册在全局命名空间的。如果我们只想让他们在当前的模块中生效,可通过添加 namespaced: true
的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action
及 mutation
都会自动根据模块注册的路径调整命名。
6.5.4 带命名空间的绑定函数
computed: {
...mapState({
a: state => state.模块X路径.状态xxx,
b: state => state.模块X路径.状态yyy,
})
},
methods: {
...mapActions([
方法1: "模块X路径/方法1",
方法2: "模块X路径/方法2",
])
}
简约法:
computed: {
...mapState('模块X路径', {
a: state => state.a,
b: state => state.b
})
},
methods: {
...mapActions('模块X路径', [
'foo',
'bar'
])
}
7. 总结在组件中调用Vuex的方法
----- | 直接调用 | 辅助函数调用 |
---|---|---|
State | this.$store.state.xxx | computed ==> …mapState([‘xxx1’,’xxx2’]) |
Getters | this.$store.getters.xxx | computed ==> …mapGetters([‘xxx1’,’xxx2’]) |
Mutations | this.$store.commit() | methods ==>…mapMutations([‘xxx1’,’xxx2’]) |
Actions | this.$store.dispatch() | methods ==>…mapActions([‘xxx1’,’xxx2’]) |
注意:当使用辅助函数时千万不要忘了引入
import { mapActions, mapState,mapGetters,mapMutations } from “vuex”;