Vuex 概述
Vuex 的组成
每一个 Vuex
应用都有一个巨大的 “视图”,这个视图的核心叫作 store
(仓库)。store
基本上就是一个数据的容器,它包含着应用中大部分的状态,所有组件之间的状态改变都需要告诉 store
,再由 store
负责分发到各个组件。
抽象一点来说,store
就像是一个全局对象,可简单地理解成 window
对象下的一个对象,组件之间的通信和状态改变都可以通过全局对象来调用,但是 store
和全局对象还是有一些本质区别的,并且也更加复杂。下面先来看看 store
由哪些部分组成,Vuex
中有默认的 5 种基本的对象:
-
state
:存储状态,是一个对象,其中的每一个key
就是一个状态。 -
getter
:表示在数据获取之前的再次编译和处理,可以理解为state
的计算属性。 -
mutation
:修改状态,并且是同步的。 -
action
:修改状态,可以是异步操作。 -
module
:store
分割后的模块,为了开发大型项目,可以让每一个模块拥有自己的state
、mutation
、action
、getter
,使得结构更加清晰,方便管理,但不是必须使用的。
上面这些对象之间的工作流程如图 6-2 所示。

上面的流程图中虽然没有标出 store
,但是可以看出,Vuex
是一个抽象的概念,而 store
是一个表现形式,是具体的对象,在代码中真正使用的是 store
,这个对象要比一般的全局对象要复杂很多。另外,Vuex
和单纯的全局对象具体有以下两点不同:
-
Vuex
的状态存储是响应式的,所谓响应式,就是说当Vue
组件从store
中读取状态时,若store
中的状态发生变化,则相应的组件也会得到高效更新。 -
不能直接改变
store
中的状态。改变store
中状态的唯一途径就是显式地提交(commit
)mutation
(这是Vuex
官方推荐的用法)。这样可以方便地跟踪记录每一个状态的变化,并且实现一些工具,帮助开发者更加全面地管理应用。
安装 Vuex
与使用 Vue.js
一样,可以在 HTML
页面中通过 <script>
标签的方式导入 Vuex
,前提是必须要先导入 Vue.js
,如示例代码 6-2-1 所示。
<script src="https://unpkg.com/vue@3.2.28/dist/vue.global.js"></script>
<script src="https://unpkg.com/vuex@4.0.0/dist/vuex.global.js"></script>
当然,可以将这个链接指向的 JavaScript 文件下载到本地计算机中,而后再从本地计算机中导入。
在使用 Vuex
开发大型项目时,推荐使用 npm
方式来安装 Vuex。npm
工具能很好地和诸如 Webpack
或 Browserify
等模块打包器配合使用。安装方法如示例代码 6-2-2 所示。
示例代码 6-2-2 使用 npm 安装 Vuex
npm install vuex@next
一个简单的store
在完成安装之后,下面来实际演示如何创建一个 store
。创建过程直截了当,仅需要提供一个初始 state
对象和一些 mutation
,如示例代码 6-2-3 所示。
const store = Vuex.createStore({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
const app = Vue.createApp({})
app.use(store) // 可以在组件中通过this.$store调用
app.mount("#app")
在上面的代码中创建了一个简单的 store
实例,store
中的状态保存在 state
中,然后可以通过 store.commit('increment')
来触发 state
状态的变更,注意 commit
方法的参数就是在 store
中定义的 mutations
的 key
值,打印 console.log(store.state.count)
,可以看到打印出了 “1”。
需要注意的是,通过提交 mutation
的方式,而不是直接改变 store.state.count
创建 store
,这是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让我们的意图更加明显,这样即使其他开发者在阅读代码时也能更容易地解读应用内部的状态改变。此外,这样也便于实现一些能记录每次状态改变和保存状态快照的调试工具,例如 Chrome 浏览器的 Vue DevTools。有了这些工具,可以实现如 “时间穿梭机” 般的调试体验。
通常情况下,如果在创建 store
时启用严格模式,那么就会绝对禁止采用直接修改 state
的方式,代码如下:
const store = createStore({
...
strict: true
})
在严格模式下,无论何时发生了状态变更且不是由 mutation
引起的,都会抛出错误。这能保证所有的状态变更都能被 Chrome 浏览器的 Vue DevTools 工具跟踪到。
由于 store
中的状态是响应式的,因此在组件中获取 store
中的状态经常会用到计算属性,并在计算属性的方法中返回 store
里面的 state
值。触发变化也仅仅是在组件的 methods
中提交 mutation
,使用起来简单便捷,代码如下:
...
computed: {
info() {
return this.$store.state.info
}
},
methods:{
changeInfo(){
this.$store.commit('changeInfo')
}
}
...
下一节将结合具体的 Vue
组件来使用 store
,并分别说明 state
、getters
、mutation
、action
、module
的使用方法。