什么是Vuex?
是一个专门在Vue中实现集中式状态管理
的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理 ,也是组件间通讯的方式。
什么时候使用Vuex?
多个组件依赖于同一个状态
来自不同的组件的行为需要变更为同一状态
Vuex的5个核心理念
- State
- Actions
- Mutations
- Getter
- Module
state
状态管理的数据核心
公共存放的数据
:用来存储变量
actions
和mutation的功能大致相同,不同之处在于 =>
1.Action提交的是mutation,而不是直接变更状态
。
2.Action可以包含任意异步操作
(ajax请求…)。
mutations
提交更新数据的方法,必须是同步的(如果需要异步使用action)。
在这里更改数据状态
每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)
getters
从基本数据(state)派生的数据,相当于state的计算属性
module
模块化
调用模式
dispatch
用于组件联系actions模块, 可传递参数
VuexComponent
this.$store.dispatch('FunName', '参数');
接收两个参数
- actions 对应处理方法名
- 携带的数据
VueActions
const actions = {
FunName(context, ...value){
···异步处理
context.commit('FUNNAME', value);
}
}
处理方法携带两个参数
context
{
state: 等同于store.state
,若在模块中则为局部状态
commit
rootState: 等同于store.state
,只存在于模块中
dispatch:
getters
rootGetter: 等同于store.getters
,只存在于模块中
}
commit
用于联系mutations
, 将数据传递给mutations更改
- VueComponent
由组件直接联系mutations
this.$store.commit('FUNNAME', value);
- actions
由actions直接联系
const actions = {
FunName(context, ...value){
···异步处理
context.commit('FUNNAME', value);
}
}
- mutations
const mutations = {
FUNNAME(state, value){
···更改状态
}
}
参数
1 state: 状态数据
2 value 通过commit传递的数据
mutate
mutations将state数据更改
getters
const getters = {
prop(state, getters){
···操作
return 计算值
}
}
参数
1 state : 操作的数据对象
2 getters:可供使用的getter
render
调用render函数渲染数据到页面
// 获取状态数据
this.$store.state.prop;
//获取计算值
this.$store.getter.prop;
基础使用
遵循模块理念
1 创建store文件夹, 创建index.js
2 引入Vuex, Vue
import Vue from 'vue';
import Vuex from 'vuex';
3 Vue.use(Vuex)
4 new Vuex.Store({})
const store = new Vuex.Store({})
5 配置5核心
import Vue from '../../node_modules/vue';
import Vuex from '../../node_modules/vuex';
Vue.use(Vuex);
//actions模块-------和mutation的功能大致相同,不同之处在于==》1.Action提交的是mutation,而不是直接变更状态。2.Action可以包含任意异步操作(ajax请求.....)。
const actions = {
};
// mutations------提交更新数据的方法,必须是同步的(如果需要异步使用action)。
// 每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)
const mutations = {
};
//从基本数据(state)派生的数据,相当于state的计算属性
const getters = {
}
//公共存放的数据-----vuex的基本数据,用来存储变量
const state = {
sum: 0,
};
const Store = new Vuex.Store({
actions,
mutations,
state,
getters,
});
export default Store;
6 暴露store
7 使用
computed: {
// 通过计算属性获取到状态
num: {
get() {
return this.$store.state.num;
},
},
getterdata: {
get() {
return this.$store.getters.cheng;
},
},
// 将数据提交到状态管理库的actions
this.$store.dispatch("add", this.num);
// or
this.$store.commit('add', this.num);
mapActions, mapMutations, mapState, mapGetters
组件绑定的辅助函数, 引入后可生成指定的store操作函数
- 普通情况下使用store的state,getters
computed:{
num(){
return this.$store.state.num;
},
sub(){
return this.$store.state.sub;
},
getNum(){
return this.$store.getters.getNum;
}
sum(){
return this.$store.getters.sum;
}
}
这样写过于繁琐
使用mapState
, mapGetters
简化写法
可以生成普通计算属性写法的计算属性函数
import {mapState, mapGetters} from 'vuex';
···
computed:{
// 当生成计算属性名和state值同名时
...mapState(['num', 'sub']),
// 当生成的计算属性名和state的计算属性名同名时
...mapGetters(['getNum','sum'])
// 当生成计算属性名和state值不同名时
...mapState({'新名称': 'state名', 'shuzi': 'num', 'jian': 'sub'}),
// 同理
...mapGetters({'新名称': '计算属性state名', 'shu': 'getNum', 'he': 'sum'}),
}
普通提交状态
this.$store.dispatch('FunName1', value);
this.$store.dispatch('FunName2', valueA);
this.$store.commit('Fun1', value);
this.$store.commit('Fun2', valueA);
当数据过于多的时候这种写法过于繁琐
使用mapActions
, mapMutations
可以生成提交状态库的代码,和mapState, mapGetters类似
import {mapActions, mapMutations} from 'vuex';
···
methods:{
// 当Vue触发的方法名和状态库中的方法同名时
...mapActions(['FunName1', 'FunName2']),
...mapMutations(['Fun1', 'Fun2']),
// 当Vue触发的方法名和状态库中的方法不同名时
// 传递一对象格式的key-vaule , key 是本地触发的方法, value是store中触发的方法
...mapActions({'fncA': 'FunName1', 'fncB': 'FunName2'}),
...mapMutations({'fn1': 'Fun1', 'fn2': 'Fun2'}),
// 当需要传递参数时。推荐使用单独方法传参
Fun(...value){
this.FunName1(value);
}
····
}
项目化(module)
当项目过大时,我们需要合理安排文件来条理化项目,vuex也是如此, 当有多个不同的模块都使用到了vuex,且数据有单独的时,我们可以在配置store时使用模块(module)来配置状态库
创建
const store = new Vuex.Store({
modules:{
'模块1':{
actions:{},
mutations:{},
stateL{},
getters:{},
},
'模块2':{···}
}
})
namespaced
命名空间,使用命名空间可以避免在提交状态库、获取状态库数据时无法指定指定模块的问题。
const store = new Vuex.Store({
modules:{
'模块1':{
namespaced: true,
actions:{},
mutations:{},
stateL{},
getters:{},
},
'模块2':{
namespaced: true,
···
}
}
})
具体使用
- 项目store结构
--- store
--- actions
--- index.js
--- mutations
--- index.js
--- getters
--- index.js
--- state
--- index.js
--- index.js ---> 实例化store, 管理modules, 出口store文件
--- util ---> 工具模块
--- ModuleStore.js ---> 实例store模块工具类
- 创建store
actions -> index.js文件
/*
模块化文件,负责专门处理每个模块的actions
*/
// 求和的actions
export const sumAct = {
addition({ commit }, value) {
console.log('加法act');
commit('ADDItion', value);
},
subtraction(store, value) {
console.log('减法act');
store.commit('subtraction', value);
}
}
// 计数的actions
export const countAct = {
countTotal({ commit }, value) {
console.log('计数act');
commit('COUNTTOTAL', value);
}
}
mutations -> index.js文件
/*
mutations, 分别处理每个模块的状态改变
*/
// 求和模块muattions
export const sumMut = {
ADDItion(state, value) {
console.log('加法mut');
state.sum = state.sum + value;
},
subtraction(state, value) {
console.log('减法mut');
console.log(state);
state.sum = state.sum - value;
}
}
// 计数模块的mutations
export const countMut = {
COUNTTOTAL(state, value) {
state.count = value;
}
}
state -> index.js文件
/*
state核心 ,保存每个模块的状态数据
*/
// 求和state
export const stateTotal = {
sum: 0
}
// 计数state
export const stateCount = {
count: 0
}
getters -> index.js文件
/*
计算属性状态
*/
export const sumGett = {
sumGG(state, b) {
console.log(state, b);
return state.sum * 10;
}
}
export const countGett = {
}
store -> index.js文件
import Vuex from 'vuex';
import Vue from 'vue';
// 引入状态库核心
import { stateTotal, stateCount } from './state';
import { sumMut, countMut } from './mutstions';
import { sumGett, countGett } from './getter';
import { sumAct, countAct } from './actions';
// 引入工具类Module
import Module from '../util/moduleStore';
Vue.use(Vuex);
// 创建私有store模块, 通过引入的module工具类实现
let sumModule = new Module(stateTotal, sumAct, sumMut, sumGett);
let countModule = new Module(stateCount, countAct, countMut, countGett);
// 创建vuex store
export default new Vuex.Store({
// 公有状态库
state: { public: '这是一段公共数据' },
// actions: {
// },
// mutations: {
// },
// getters: {
// },
// 功能私有状态库
modules: {
sumModule,
countModule
}
});
moduleStore.js
/*
通过工具类生成 store Module
- state
- actions
- mutations
- getter
+ namespaced --- 命名空间声明, 有独立模块必需使用此声明
*/
export default class Moudel {
constructor(state, actions, mutations, getters) {
this.namespaced = true;
this.state = state;
this.actions = actions;
this.mutations = mutations;
this.getters = getters;
}
}
状态库数据的提交与获取
- 获取
computed: {
// 生成了以状态值名的计算属性获取
...mapState("sumModule", ["sum"]),
// 相当于
// sum() {
// return this.$store.state.sumModule.sum;
// },
...mapGetters("sumModule", ["sumGG"]),
// 相当于
// sumGG() {
// return this.$store.getters["sumModule/sumGG"]
// },
...mapState("countModule", ["count"]),
},
- 提交
methods: {
add(newValue) {
// this.$store.dispatch("sumModule/addition", newValue);
// this.$store.commit("sumModule/ADDItion", newValue);
this.addition(newValue);
this.count++;
this.countTotal(this.count);
},
subtr(newValue) {
// 调用store提交状态数据
this.subtraction(newValue);
this.count++;
this.countTotal(this.count);
},
...mapActions("sumModule", ["addition"]),
// 相当于
// addition(newValue) {
// this.$store.dispatch("sumModule/addition", newValue);
// },
...mapActions("countModule", ["countTotal"]),
...mapMutations("sumModule", ["subtraction"]),
// 相当于
// subtraction(newValue) {
// this.$store.commit("sumModule/subtraction", newValue);
// },
},
使用 modules 化 更便于维护, 注意别少了命名空间声明。
以上代码也并非是完全条理化
使用map···等函数可以使开发更高效。