前端面试系列【012】 - 谈一谈你对 vuex 的理解

214 阅读4分钟

作为 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 的理解