vuex
vuex 是什么
vuex 是专门为 vue 应用程序设计的状态管理工具。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
设计思想
vuex 的设计思想借鉴了 Flux、Redux,将数据存储在全局的 store,再将 store 挂载到每个 vue 实例组件中,利用 vue 的细粒度数据响应机制来进行高效的状态更新
原理解析
主要理解两个问题
- vuex 的 store 是如何挂载注入到组件中呢?
- vuex 的 state 和 getters 是如何映射到各个组件实例中响应式更新状态呢?
vuex 的 store 如何挂载注入到组件中
首先安装 vuex
import Vuex from 'vuex';
Vue.use(Vuex);
由于 vue 的插件机制,在使用Vue.use(vuex)时,会调用 vuex 的 install 方法来装载 vuex,install 方法如下
export function install(_Vue) {
if (Vue && _Vue === Vue) {
if (process.env.NODE_NEV !== 'production') {
console.error(
'[vuex] already install. Vue.use(Vuex) should be called only once'
);
}
return;
}
Vue = _Vue;
applyMixin(Vue);
}
applyMixin 方法使用了 vue 的混入机制,在 vue 的声明周期 beforeCreate 钩子函数前混入 vuexInit 方法,核心代码如下
Vue.mixin({ beforeCreate: vuexInit });
function vuexInit() {
const options = this.$options;
if (options.store) {
this.$store =
typeof options.store === 'function'
? options.store()
: options.store;
} else if (options.parent && options.parent.$store) {
this.$store = optioins.parent.$store;
}
}
小结:通过分析源码得知,vuex 利用了 vue 的 mixin 混入机制,在 beforeCreate 钩子前混入 vuexInit 方法,vuexInit 方法实现了 store 注入 vue 组件实例,并且注册了 vuex store 的引用属性$store,store 注入 过程如下图 
vuex 的 state 和 getters 是如何映射到各个组件实例中响应式更新状态
store 实现的源码在 src/store.js
核心方法 resetStoreVM 如下
function resetStoreVM(store, state, hot) {
const oldVm = store._vm;
store.getters = {};
const wrappedGetters = store._wrappedGetters;
const computed = {};
forEachValue(wrappedGetters, (fn, key) => {
// 给 computed 对象添加属性
computed[key] = partial(fn, store);
// 重写 get 方法,store.getters.xx 其实是访问了store._vm[xx],其中添加 computed 属性
Object.defineProperty(store.getters, key, {
get: () => store._vm[key],
enumerable: true,
});
});
const silent = Vue.config.silent;
Vue.config.silent = true;
// 创建 Vue 实例来保存 state,同时让 state 变成响应式
// 这里代码才是核心,其实就是把 store 变成一个隐藏组件的 data
store._vm = new Vue({
data: {
$$state: state,
},
computed,
});
Vue.config.silent = silent;
// 只能通过 commit 方式更改状态
if (store.strict) {
enableStrictMode(store);
}
}
从上面源码可以看出 vuex 的 state 状态是响应式,是借助 vue 的 data 生成的,将 store 存入 一个隐藏的 vue 实例组件的 data 中;vuex 的 getters 则是借助 vue 的计算属性 computed 实现数据监听
computed 计算属性监听 data 数据变更主要经历以下几个过程

总结
vuex 是通过全局注入 store 对象,来实现组件间的状态共享。在大型复杂的项目中(多级组件嵌套),需要实现一个组件更改某个数据,多个组件自动获取更改后的数据进行业务逻辑处理,这时候使用 vuex 比较合适。假如只是多个组件间传递数据,使用 vuex 未免有点大材小用,其实只用使用组件间常用的通信方法即可。
一句话结束 vuex 工作原理:vuex 中的 store 本质就是没有 template 的隐藏着的 vue 组件;