Vuex 状态管理总结
一、 认识 Vuex
1. Vuex 是干什么的:对 Vue 的应用中多个组件的共享状态进行集中式的管理(读/写)
2. Vuex 能解决什么问题?我们应该在什么样的场景下使用?
- 场景:多个组件(视图)依赖同一个状态,来自不同的组件(视图)需要变更同一状态。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LwhOq4Oq-1657074863531)(1.png)] - 传统的组件之间共享状态的方式。父子组件通过 props 来进行通信。兄弟组件和嵌套较深的祖宗后代组件之间的通信使用总线通信。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vcXaiBJU-1657074863532)(2.png)] - 使用场景总结:多个组件需要共享同一状态。
- 传统方法缺点:1、操作繁琐,代码逻辑繁杂,不方便统一管理数据状态。2、不能很好监听数据状态的变化,对开发不友好,不便于调试。
- vuex 优点:1、操作简单,代码逻辑清晰,方便统一管理数据状态。2、使用开发者工具,可以很好地监听 store 中数据状态的变化,方便调试。
二、安装 Vuex
1. 在项目创建之初可以勾选 vuex 使用 vuex。
2. 若创建项目之初没有勾选 vuex,则可以使用 npm install vuex 或 yarn add vuex 进行安装。
- 注意 vuex 的版本和 vue 版本需要配套。vue 版本为 2.x,vuex 版本需要为 3.0,vue 版本为 3.x,vuex 版本需要为 4.0。手动安装时需要指定版本号。
三、Vuex 的配置
1. vuex 的配置文件 store/index.js 文件中:
import Vue from 'vue'; // 引入vue
import Vuex from 'vuex'; // 引入vuex
Vue.use(Vuex); // 使用vuex 进行拦截
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
getters: {},
modules: {}
});
2. 在main.js中将store对象挂载到vue实例中。
new Vue({store, render: h => h(App)}).$mount('#app')
三、Vuex 的使用
1.vuex工作流程
- View -> Actions -> Mutations -> State -> View
2. store文件夹中index.js中vuex书写
//state是存放数据的仓库
state: {
name: 'liujue'
},
//mutations更改仓库中的数据。这里第一个形参state就是仓库中的state对象,params为接收的参数。只能同步修改,不能做异步修 改。
mutations: {
nameMutation (state, params) {
state.name = params
}
},
// actions是异步操作获取数据的方法。这里的形参是上下文对象,里面有commit方法,可以提交相关mutations函数,然后mutations 执行,从而达到修改state中数据的目的。
actions: {
nameAction (context) {
store.commit( 'nameMutation', 'liujiajia' )
}
},
//getters加工仓库中的数据,相当于store中的计算属性
getters: {
gettersName (state) {
return state.name + '--getters'
}
}
// 每个module拥有自己的state, getters, mutation, action
const moduleA = {namespace: true, state: {}, getters: {}, mutations: {}, actions: {}}
const moduleB = {namespace: true, state: {}, getters: {}, mutations: {}, actions: {}}
// 在Vuex.Store中配置modules参数。
new Vuex.Store( { modules: { a: moduleA, b: moduleB } }
3. view文件中操作state的方法
-
vuex模块化与命名空间
- 查看vue实例上的store对象
-
页面中四种获取state的方法:
- 直接读取state
未使用模块:this.$store.state.name
,使用模块化:this.$store.state.moduleName.name
- 通过getters获取
未使用模块或模块中未设置命名空间:this.$store.getters.gettersName
,模块化且设置命名空间:this.$store.getters["moduleName/gettersNameA"]
- 使用…mapState
1、数组形式。未使用模块化:...mapState(["name"])
,使用模块化:...mapState("moduleName", ["nameA"])
。
2、对象形式。未使用模块化或使用模块化但未开启命名空间:...mapState({myName: 'name'})
或...mapState({ name : state => state.name})
,使用模块且开启了命名空间:...mapState("moduleName", {myName: 'name'})
或...mapState ("moduleName", { nameA : state => state.nameA })
。 - 使用…mapGetters
1、数组形式。未使用模块或使用模块未设置命名空间:...mapGetters(["gettersName"])
,使用模块且设置了命名空间:...mapState("moduleName", ["gettersNameA"])
2、对象形式。未使用模块或使用模块未设置命名空间:...mapGetters({gettersName: "gettersName"})
,使用模块且设置了命名空间:...mapGetters("moduleName", {gettersNameA: "gettersNameA"})
- 直接读取state
-
页面中五种修改state的方法
- 直接操作state
不建议使用,会导致数据操作紊乱,不方便调试,不经过mutation,不方便使用开发工具进行调试。
未使用模块:this.$store.state.name = "六六六"
,使用模块化:this.$store.state.moduleName.name = "六六六"
- 使用
this.$store.commit
方法,同步操作
未使用模块化和使用模块化但未设置命名空间:this.$store.commit("mutationsName","mutationsName")
,使用模块化且设置了命名空间:this.$store.commit("mutationsNameB", "mutationsNameB")
- 使用
this.$store.dispatch
,异步操作
未使用模块化和使用模块化但未设置命名空间:this.$store.dispatch("actionsName", "dispatchName")
,使用模块化且设置了命名空间:this.$store.dispatch("moduleName/actionsNameA", "dispatchNameA")
- 使用…mapMutations
1、数组形式:未使用模块化或使用模块化未设置命名空间:...mapMutations(["mutationsName"])
,使用模块化且设置了命名空间:...mapMutations("moduleName", ["mutationsNameA"])
2、对象形式:未使用模块化和使用模块化未设置命名空间:mapMutations({mutationsName: "mutationsName"})
,使用模块化且设置了命名空间:...mapMutations("moduleName", {mutationsNameA: "mutationsNameA"})
- 使用…mapActions
1、数组形式:未使用模块化和使用模块化未设置命名空间:...mapActions(["actionsName"])
,使用模块化且设置了命名空间:...mapActions("moduleName", ["actionsNameA"])
2、对象形式:未使用模块化和使用模块化未设置命名空间:...mapActions({actionsName: "actionsName"})
,使用模块化且设置了命名空间:...mapActions("moduleName", {actionsNameA: "actionsNameA"})
- 直接操作state