为什么使用Vuex?
Vue1.x升级到Vue2.x做了很大的改动,其中Vuex状态管理层的概念是最重大的改动之一。
关于Vuex是什么、为什么使用Vuex的原因,请阅读Vue和Vuex的官方文档:
Vuex的官方文档已经解释的很清楚了:
但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
- 多个视图依赖于同一状态。
- 来自不同视图的行为需要变更同一状态。
对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。
因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
简洁地讲:
Vuex的作用就是将多个组件之间的共享状态抽取出来,统一管理。
Vuex的用法
# 安装
Vuex的安装非常简单,如果项目没有用到Webpack、gulp等项目构建工具,直接到官网下载js源码,html文件中加载js文件即可。
# Store仓库
每一个 Vuex 应用的核心就是 store(仓库)。"store" 基本上就是一个容器,它包含着你的应用中大部分的状态(state)。Vuex 和单纯的全局对象有以下两点不同:
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交(commit) mutations。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
在创建Vue实例之前创建Vuex实例:
const store = new Vuex.Store({
state: {
var1: xxx,
var2: xxx,
var3: xxx
},
mutations: { // 同步执行,不支持异步执行,所有数据变化只能通过mutations中的方法修改
setState1 (state, argument) {
state.var1 = argument.value;
},
setState2 (state, value) {
state.var2 = value;
},
setState3 (state, value) {
state.var3 = value;
}
},
actions: { // 支持异步执行, 也即方法内的事务不需要保证原子性
doAction1 (context) { // context参数并不是store对象本身
context.commit('setState1', {value:false});
},
doAction2 (context) {
context.commit('setState2', 'xxx');
context.commit('setState3', {value:true});
}
},
getters: {
getVar1: state => {
return state.var1;
},
getVar2: state => {
return state.var2;
},
getVar3: state => {
return state.var3;
}
},
modules: {
component1: component1Module,
component2: component2Module,
component3: component3Module
}
});
在上述代码中,可以看到5个构造器选择器:state、mutations、actions、getters、modules。
- state: 在里面定义状态变量
- mutations: 定义改变状态的方法,而且是原子性的
- actions: 定义执行的一组事务,不是原子性的
- getters:定义外界读取状态的方法
你还可以看到最后一个构造器选项:modules,没错,Vuex支持模块化,Vue的每一个组件component都可以维护一个对应的store模块。
在创建Vuex Store实例之前,创建所有组件component的store模块:
const component1Module = {
state: {
var1: xxx,
var2: xxx,
var3: xxx
},
mutations: {
setComponent1Var1 (state, value) {
state.var1 = value;
},
setComponent1Var2 (state, value) {
state.var2 = value;
},
setComponent1Var3 (state, value) {
state.var3 = value;
}
},
actions: {
doComponent1Action1 ({ state, commit }, argument) {
commit('setComponent1Var1', argument.var1);
commit('setComponent1Var2', argument.var2);
commit('setComponent1Var3', argument.var3);
}
},
getters: {
getComponent1Var1: state => {
return state.var1;
},
getComponent1Var2: state => {
return state.var2;
},
getComponent1Var3: state => {
return state.var3;
}
}
}
创建Vue实例时加上store选项即可:
new Vue({
el: "#app",
store,
data: {
},
// 选项
...
});
到这里,Vuex的模块化构建工作就完成了。Vue实例和各个组件就可以直接用this.$store调用Vues实例了。
- 触发一次状态更改:this.$store.commit('setComponent1Var1', argument);
- 触发一次事务执行:this.$store.dispatch('doComponent1Action1', argument);
- 获取状态: this.$store.getters.getComponent1Var1;
注意,获取状态变量不是this.$store.getters.getComponent1Var1()。
如果store实例是全局变量,直接用store变量就可以:
- 触发一次状态更改:store.commit('setComponent1Var1', argument);
- 触发一次事务执行:store.dispatch('doComponent1Action1', argument);
- 获取状态: store.getters.getComponent1Var1;
基本上Vuex的核心知识就这么多,很容易上手吧~
网友评论