作为 vue 全家桶之一,想必大家对 vuex 并不陌生,相反还非常熟悉。
显然,对于这个问题,如果仅仅回答如何使用 vuex 是不合格的。既然问理解,自然要有自己的,更深层次的想法。
那么对于这个问题,我们应该从以下角度层层递进的来回答:
- 什么是 vuex?
- 为什么要使用 vuex?
- 在什么场景下使用?
- 如何使用?
- vuex 底层的实现原理是什么?
什么是 vuex?
对于这个问题,显然官方的回答是最权威的:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
上面的解释不可谓不精炼了:首先,开门见山的回答了我们的问题, vuex 是针对 vue 的状态管理模式。
它是怎么进行管理的呢?对于这个问题,它又提出了两个关键词:
- 集中式
- 可预测
想要较好的理解整个流程,我们可以借助官方的数据流向图:
可以看到,vuex 将整个 store 抽象出来:组件中的状态全都来自于 state,而如果想要修改 state,则必须通过 dispatch action,然后 action 中通过 mutation 来修改 state。
- 状态被抽离出来,统一管理,这是集中式
- 而所有修改状态都必须由 mutaions 来完成,所以可预测
为什么要使用 vuex?
对于这个问题,可能有的人存在理解上的偏差。
为什么要使用 vuex?
为了实现组件之间的数据互通呀!
乍一看这个说法似乎没什么问题,vuex 的确实实现了组件之间的数据通信,但这却并不是要使用 vuex 的原因。
实际上能够实现组件见数据互通的方法很多:比如 even bus、pro/inj、Pubsub 等。
使用 vuex 的真正原因在于:集中式管理全局状态。
在项目的开发中,每个组件都会有自己的状态,事件,我们可以通过事件修改状态,从而影响组件的展示,然而当随着项目逐渐变得复杂的时候,很容易就出现了下面的情况:
并且在这样错综复杂 state 更新的情况下,还会出现状态不统一的问题,这个时候,到底谁才是正确的状态往往也是非常令人头疼的问题。而如果将 state 抽离出来集中式的管理,则可以避免很多问题:
在什么场景下使用?
从上面我们可以知道,vuex 适用于比较复杂的项目,而对于一些小型的玩具应用来说,状态本身并不多,也不复杂,强行使用 vuex 反倒会增加其开发成本。
那么在应用规模达到什么地步的时候使用 vuex 呢?
对于这个问题,其实可以引用 Redux 作者的一句原话:
Flux 架构就像眼镜:您自会知道什么时候需要它。
当项目规模逐渐扩大,状态维护逐渐变得脆弱和困难的时候,作为开发者肯定是感受非常深刻的。就像眼镜一样,当你看不清楚的时候,你就会需要它了,当你感觉无力维护如此庞大而复杂的状态的时候,你就需要 vuex 了。
如何使用?
对于这个问题,我们可以参考 vue-element-admin,这里面有非常的多 vue 最佳实践,当然,也包括如何使用 vuex。
vuex 的底层原理是什么?
对于这个问题,我们可以先看看这篇文章:手写简易 vuex。
vuex 最核心的问题显然是响应式数据的实现,在 vuex 源码中,它的实现方案为:创建一个 vue 实力,利用其中 data 数据是响应式的,将自己的 state 转化为响应式数据,大致代码如下:
export default {
/*...*/
Store: class Store {
constructor(options) {
this._mutations = options.mutations
this._vm = new _Vue({
data() {
return {
// 由于不希望数据被代理,所以这里加上 $
$$state: options.state,
}
}
})
}
get state() {
return this._vm._data.$$state
}
set state(value) {
// 不允许直接修改 state
console.error('please use replaceState to reset state')
}
/*...*/
},
}
另外,vue 还对外暴露了 Vue.util.defineReactive 方法,同样可以定义响应式数据。
结语
更佳阅读体验:012 - 谈一谈你对 vuex 的理解