Vuex4 介绍

TIP

Vuex 4 与 Vue 3 匹配

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

什么是“状态管理模式”

从一个简单的 Vue 计数应用开始

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const Counter = {
// 状态
data () {
return {
count: 0
}
},
// 视图
template: `
<div>{{ count }}</div>
`,
// 操作
methods: {
increment () {
this.count++
}
}
}

createApp(Counter).mount('#app')

这个状态自管理应用包含以下几个部分:

  • 状态,驱动应用的数据源;
  • 视图,以声明方式将状态映射到视图;
  • 操作,响应在视图上的用户输入导致的状态变化。

一个表示“单向数据流”理念的简单示意:

img

当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

  • 多个视图依赖于同一状态。
  • 来自不同视图的行为需要变更同一状态。

对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。

对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。

把组件的共享状态抽取出来,以一个全局单例模式管理,在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!

vuex

什么情况下我应该使用 Vuex?

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

安装

直接下载 / CDN 引用

https://unpkg.com/vuex@4

Unpkg.com 提供了基于 npm 的 CDN 链接。以上的链接会一直指向 npm 上发布的最新版本。您也可以通过 https://unpkg.com/vuex@4.0.0/dist/vuex.global.js 这样的方式指定特定的版本。

在 Vue 之后引入 vuex 会进行自动安装:

1
2
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>

npm

1
npm install vuex@next --save

Yarn

1
yarn add vuex@next --save

自己构建

直接从 GitHub 上克隆代码并自己构建。

1
2
3
4
git clone https://github.com/vuejs/vuex.git node_modules/vuex
cd node_modules/vuex
yarn
yarn build

开始

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的**状态 (state)**。

Vuex 和单纯的全局对象有以下两点不同:

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

最简单的 Store

安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 state 对象和一些 mutation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { createApp } from 'vue'
import { createStore } from 'vuex'

// 创建一个新的 store 实例
const store = createStore({
state () {
return {
count: 0
}
},
mutations: {
increment (state) {
state.count++
}
}
})

const app = createApp({ /* 根组件 */ })

// 将 store 实例作为插件安装
app.use(store)

可以通过 store.state 来获取状态对象,并通过 store.commit 方法触发状态变更

1
2
3
store.commit('increment')

console.log(store.state.count) // -> 1

在 Vue 组件中, 可以通过 this.$store 访问store实例。

1
2
3
4
5
6
methods: {
increment() {
this.$store.commit('increment')
console.log(this.$store.state.count)
}
}

通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。

由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutation。