一. Vuex 是什么?
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享。
二. 使用 Vuex 统一管理状态的好处
- 能够在vuex中集中管理共享的数据,易于开发和后期维护。
- 能够高效的实现组件之间的数据共享,提高开发效率。
- 存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步。
三. 什么样的数据适合存储到 Vuex 中
一般情况,只有组件之间共享的数据,才有必要存储到vuex中;对于组件中的私有数据,依旧存储在组件自身的data中即可。
四. Vuex 的基本使用
-
安装vuex依赖包
npm install vuex --save
-
src
目录下创建store.js
文件
-
配置
store.js
文件
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ //state中存放的就是全局共享的数据 state: { count: 0 }, mutations: {}, actions: {} })
-
main.js
中导入store.js
import Vue from "vue"; import App from "./App.vue"; import router from "./router"; // 引入store import store from "./store"; Vue.prototype.$store = store; Vue.config.productionTip = false; new Vue({ el: "#app", router, components: { App }, template: "<App/>", store, });
五. Vuex 的核心概念
Vuex中的主要核心概念如下:
- State
- Mutation
- Action
- Getter
5.1 State
State
提供唯一的公共数据源,所有共享的数据都要统一放到Store
的State
中进行存储。
5.1.1 store.js 中创建store数据源,提供唯一公共数据:
export default new Vuex.Store({
State:{
//创建store数据源,提供唯一公共数据
count:0
}
})
5.1.2 组件访问 State 中数据的两种方式
- 第一种方式:
this.$store.state.全局数据名称
this.$store.state.count
- 第二种方式:
通过导入的//1.使用vuex的组件中,从vuex中按需导入mapState函数 import { mapState } from 'vuex'
mapState
函数,将当前组件需要的全局数据,映射为当前组件的computed
计算属性://2.将全局数据,映射为当前组件的 计算属性,这里的全局数据为count computed:{ ...mapState(['count']) }
5.2 Mutations
Mutation
用于变更Store
中的数据。- 只能通过
mutation
变更Store
数据,不可以直接操作Store中的数据。 - 通过这方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
- 只有
mutations
中定义的函数,才有权力修改state
中的数据。 - 在
Mutations
中,不可执行异步操作,只允许写同步的代码。
5.2.1 触发 Mutations 修改数据的两种方法
-
store.js 中定义 Mutations
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state:{ count:0 }, mutation:{ //变更Store中的数据状态的方法 add(state) { state.count++ }, sub(state) { state.count-- }, //state:数据存储库;step:参数 addN(state, step) { state.count += step }, subN(state, step) { state.count -= step } } }
-
组件中触发 Mutations
- 第一种方法
this.$store.commit('Mutations中的方法名')
methods:{ Handle(){ //调用commit函数执行store中的add方法 this.$store.commit('add') } }
- 第二种方法
通过导入的// 1.从vuex中按需导入mapMutations函数 import {mapState,mapMutations} from 'vuex'
mapMutations
函数,映射为当前组件的methods
函数::methods:{ //2.将指定的mapMutations函数,映射为当前组件的methods函数 ...mapMutations(['add','sub','addN','subN']), // 3.使用 btnhandleOne(){ this.sub() } }
5.2.2 触发 Mutations 传递 参数 修改数据
- store.js 中定义 Mutations
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state:{ count:0 }, mutation:{ //变更Store中的数据状态的方法 add(state) { state.count++ }, sub(state) { state.count-- }, //state:数据存储库;step:参数 addN(state, step) { state.count += step }, subN(state, step) { state.count -= step } } }
- 组件中触发 Mutations
- 第一种方法
methods:{ btnHandlerOne(){ //调用commit函数执行store中的addN方法,所传参数为3 this.$store.commit('addN',3) } }
- 第二种方法
通过导入的// 1.从vuex中按需导入mapMutations函数 import {mapState,mapMutations} from 'vuex'
mapMutations
函数,映射为当前组件的methods
函数:methods:{ //2.将指定的mapMutations函数,映射为当前组件的methods函数 ...mapMutations(['add','sub','addN','subN']), // 3.使用 btnHandleTwo(){ this.subN(3) } }
5.3 Actions
Action
可以处理任意异步操作。- 如果通过异步操作变更数据,必须通过
Action
,而不能使用Mutations
,但是在Action
中还是要通过触发Mutation
的方式间接变更数据。 - 在
action
中,不能直接修改state
中的数据,必须通过context.commit()
触发mutations
才行。
5.3.1 通过异步操作变更数据的两种方法
-
store.js 中定义 Actions
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ //state中存放的就是全局共享的数据 state: { count: 0 }, //只有mutations中定义的函数,才有权力修改state中的数据。 mutations: { add(state) { state.count++ }, //state:数据存储库;step:参数 addN(state, step) { state.count += step }, sub(state) { state.count-- }, subN(state, step) { state.count -= step } }, //在action中,不能直接修改state中的数据。 //必须通过context.commit()触发mutations才行 actions: { //context: Vuex实例对象 addAsync(context){ setTimeout(()=>{ //通过commit触发mutations中的方法 context.commit('add') },1000) }, addNAsync(context,step){ setTimeout(()=>{ //通过commit触发mutations中的方法 context.commit('addN',step) },1000) }, subAsync(context){ setTimeout(()=>{ //通过commit触发mutations中的方法 context.commit('sub') },1000) }, subNAsync(context,step){ setTimeout(()=>{ //通过commit触发mutations中的方法 context.commit('sub',step) },1000) }, } })
-
组件中触发 Actions
- 第一种方法
methods:{ btnHandlerThree(){ //这里的dispatch函数,用来触发action this.$store.dispatch('addAsync') } }
- 第二种方法
通过导入的// 1.从vuex中按需导入mapActions函数 import {mapState,mapMutations,mapActions} from 'vuex'
mapActions
函数,映射为当前组件的methods
函数methods:{ //2.将指定的mapMutations函数,映射为当前组件的methods函数 ...mapActions(['addAsync','addNAsync','subAsync','subNAsync']), // 3.使用 btnhandleThree(){ this.subAsync() }, }
5.3.2 触发actions异步任务时携带 参数
- store.js 中定义 Actions
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ //state中存放的就是全局共享的数据 state: { count: 0 }, //只有mutations中定义的函数,才有权力修改state中的数据。 mutations: { add(state) { state.count++ }, //state:数据存储库;step:参数 addN(state, step) { state.count += step }, sub(state) { state.count-- }, subN(state, step) { state.count -= step } }, //在action中,不能直接修改state中的数据。 //必须通过context.commit()触发mutations才行 actions: { //context: Vuex实例对象 addAsync(context){ setTimeout(()=>{ //通过commit触发mutations中的方法 context.commit('add') },1000) }, addNAsync(context,step){ setTimeout(()=>{ //通过commit触发mutations中的方法 context.commit('addN',step) },1000) }, subAsync(context){ setTimeout(()=>{ //通过commit触发mutations中的方法 context.commit('sub') },1000) }, subNAsync(context,step){ setTimeout(()=>{ //通过commit触发mutations中的方法 context.commit('sub',step) },1000) }, } })
- 触发 actions
- 第一种方法
methods:{ HandlerFour(){ this.$store.dispatch('addNAsync',5) } }
- 第二种方法
通过导入的// 1.从vuex中按需导入mapActions函数 import {mapState,mapMutations,mapActions} from 'vuex'
mapActions
函数,映射为当前组件的methods
函数methods:{ //2.将指定的mapMutations函数,映射为当前组件的methods函数 ...mapActions(['addAsync','addNAsync','subAsync','subNAsync']), // 3.使用 btnhandleFour(){ this.subNAsync(5) } }
5.4 Getters
Getter
用于对Store
中的数据进行加工处理形成新的数据。Getter
可以对Store
中已有的数据进行加工处理之后形成新的数据,类似Vue
的计算属性。Store
中的数据发生变化,Getter
的数据也会跟着变化。
5.4.1 使用 Getters 的两种方法
- store.js 中定义 Getters
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ //state中存放的就是全局共享的数据 state: { count: 0 }, getters:{ showNumber(state){ return '最新数据:'+ state.count +'' } } })
- 触发 Getters
- 第一种方法
this.$store.getters.名称
this.$store.getters.showNumber
- 第二种方法
通过导入的// 1.从vuex中按需导入 mapGetters 函数 import {mapState,mapMutations,mapActions,mapGetters} from 'vuex'
mapGetters
函数,映射为当前组件的computed
计算属性computed:{ //2.将指定的mapGetters函数,映射为当前组件的 计算属性 ...mapGetters(['showNumber']), },
<template> <div> <!-- 使用 store.js 中 getters 的 showNumber --> <h3>{{showNumber}}</h3> </div> </template>