概念:
Vuex 是专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对应 Vue 应用中的多个组件的共享状态的进行集中式的管理(读 / 写),也是一种组件间通信的方式,且适于任意组件间通信。
使用 Vuex 的时机
多组件依赖于同一状态
来自不同组件的行为需要变更为同一状态
现在我们来引入一个背景,说明为什么要引入 Vuex。
场景:A B C D四个组件,大家都想用A组件的x属性对其进行读/写
1- 全局事件总线实现(其实兄弟组件用最香),(红线是读/绿线是写),如图
1- 纯vue求和案例
当前求和的值{{ sum }}
首先,每一个 Vuex 应用的核心就是 store,它负责管理统一的状态和数据
1- state(数据)
Vuex 管理的状态对象,它是唯一的
2- actions(事件)** 侧重写业务逻辑
1.值为一个对象,包含多个响应用户动作的回调函数;
2.通过 commit() 来触发 mutation 中的函数的调用,间接更新 state
3.触发 axios 中的回调:$store.dispatch('对应的 action 回调名') 来触发
4.可以包含异步代码(定时器、Ajax 等)
3-mutations(执行)**侧重操作数据
1.值为一个对象,包含多个直接更新 state 的方法
2.调用 mutations 中方法:在 action 中使用 commit('对应的 mutations 方法名') 来触发
3.特点:不能写异步代码、只能单纯地操作 state
1- 安装 npm i vuex@3
2.创建
src/store/index.js
,该文件用于创建Vuex
中最为核心的store
import Vue from 'vue'
import Vuex from 'vuex' // 引入 vuex
Vue.use(Vuex) // 使用 vuex 插件
const actions = {} // 准备 actions —— 用于响应组件中动作
const mutations = {} // 准备 mutations —— 用于操作数据(state)
const state = {} // 准备 state —— 用于存储数据
// 创建并暴露 store
export default new Vuex.Store({
actions,
mutations,
state,
})
3-在
src/main.js
中创建vm
时传入store
配置项
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 引入 store
import store from './store'
new Vue({
render: h => h(App),
store, // 配置项添加 store
}).$mount('#app')
src\store\index.js 编写需要调用的函数,
action中函数 dispatch 调用(可以写异步函数 比如axios 发送请求),
mutations —— 用于操作数据(state) (commit 直接 调用)
import Vue from 'vue'
import Vuex from 'vuex' // 引入 vuex
Vue.use(Vuex) // 使用 vuex 插件
//3-1 准备 actions —— 用于响应组件中动作 (dispatch 调用)
const actions = {
incrementOdd(context, value) {
if(context.state.sum % 2) {
context.commit('INCREMENT', value);
}
},
incrementWait(context, value) {
setTimeout(() => {
context.commit('INCREMENT', value);
}, 500)
}
}
// 2-1 准备 mutations —— 用于操作数据(state) (commit 直接 调用)
const mutations = {
//准备函数
INCREMENT(state, value) {
state.sum += value;
},
DECREMENT(state, value) {
state.sum -= value;
},
}
// 1- 准备 state —— 用于存储数据
const state = {
sum: 0 //定义总数
}
// 创建并暴露 store
export default new Vuex.Store({
actions,
mutations,
state,
})
1- Count.vue中 commit 或者 dispatch 直接调用 index.js中函数 ,并修改 state 对象中存储的 属性
2-组件中读取 Vuex中 属性 {{$store.state.sum}}
当前求和的值{{$store.state.sum}}
用于对state中的数据进行加工(比如 sun)
…
const getters = {
bigSum(state) {
return state.sum * 10
}
}
// 创建并暴露 store
export default new Vue.Store({
…
getters
…
})
组件中读取
当前求和的值*10{{$store.getters.bigSum}}
作用 :
1- mapState 帮我映射 state 中的数据生成计算属性
2-mapGetters 帮我映射 getters 中的数据生成计算属性
对比下面代码计算属性实现数据的读取,我们使用 mapState 和 mapGetters 帮我完成
当前求和的值{{ sum }}
当前求和的值*10{{ bigSum }}
我在{{ school }}学习 {{ subject }}
我们继续对 method 中的 commit 和 dispatch进行更改
1- mapMutations: 生成 commit 调用 mutations
2- mapActions: 生成 dispatch 调用 action
注意: 2处 调用时传递值
当前求和的值{{ sum }}
当前求和的值*10{{ bigSum }}
我在{{ school }}学习 {{ subject }}
后红色部分是获取对方组件的属性
1- store目录下新建 count.js 并暴露
//1- 定义求和相关的配置
export default {
//1-1 开启配置
namespaced: true,
actions: {
incrementOdd(context, value) {
if (context.state.sum % 2) {
context.commit('INCREMENT', value);
}
},
incrementWait(context, value) {
setTimeout(() => {
context.commit('INCREMENT', value);
}, 500)
}
},
mutations: {
INCREMENT(state, value) {
state.sum += value;
},
DECREMENT(state, value) {
state.sum -= value;
}
},
state: {
sum: 0,
school: 'vue学院',
subject: 'Vue2',
},
getters: {
bigSum(state) {
return state.sum * 10
}
}
}
2-stor 目录下 新建 persons.js 并且暴露
//2- 定义person相关的配置
export default {
//2-1 开启配置
namespaced: true,
actions: {},
mutations: {
ADDPERSON(state, personObj) {
state.personList.unshift(personObj);
}
},
state: {
personList: [
{ id: '11', name: '张三' }
]
},
getters: {
firstPersonName(state){
return state.personList[0].name
}
}
}
3- src/index.js 中按组件分组
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//4-引入
import countOptions from './count'
import personOptions from './persons'
// 3- 创建并暴露 store 合并各个组件的配置
export default new Vuex.Store({
modules: {
conutAbout: countOptions,
personAbout: personOptions
}
})
4-count组件中 mapState, mapGetters, mapActions, mapMutations 获取stroe中属性的写法
当前求和的值{{ sum }}
当前求和的值*10{{ bigSum }}
我在{{ school }}学习 {{ subject }}
Persons组件的总人数是:{{ personList.length }}
5- person 组件
commit dispath 的写法 : this.$store.commit("personAbout/ADDPERSON", person);
分组中获取getters : this.$store.getters['personAbout/firstPersonName']
Count组件的求和是:{{ sum }}
第一个人的姓名是{{ firstName }}
人员列表
- {{ p.name }}