二次元绘画创作
56.21M · 2026-02-04
在构建中大型 Vue 单页应用时,组件间的通信往往会变得复杂。Vuex 作为一个专为 Vue.js 应用程序开发的状态管理模式 + 库,采用集中式存储管理应用的所有组件的状态。本文将带你从核心概念到持久化方案,深度拆解 Vuex 的运行机制。
Vuex 采用全局单例模式,将组件的共享状态抽取出来进行管理。它解决了以下两大痛点:
Vuex 规定:组件可以读取 State,但严禁直接修改 State。这种约束确保了状态变更的可预测性和可追溯性。
存储数据的唯一数据源,类似于组件的 data,只可以读,不能进行写操作。
有些时候我们需要对获取的数据进行加工,获取数据的一部分或者某些属性,而不是直接获取state中的数据时,这时候可以通过getter定义函数,返回对应的数据。
唯一能修改 State 的地方,在vue组件中可以通过commit触发修改函数。不过mutations里面的操作必须是同步的。
用于处理异步逻辑(如 API 请求),通过提交 (commit) Mutation 来间接修改 State。
当 Store 对象变得臃肿时,可以将其拆分为多个子模块,每个模块拥有独立的五大核心概念。
Store 定义 (store/index.ts):
import { createStore, ActionContext } from 'vuex'
// 1. 定义 State 类型
interface PersonalInfo {
name: string
age: number
}
interface State {
personalInfo: PersonalInfo
}
export default createStore<State>({
state: {
personalInfo: {
name: "Liu",
age: 27
}
},
// 同步修改数据
mutations: {
CHANGE_INFO_NAME(state) {
state.personalInfo.name = "Rick"
}
},
// 异步触发逻辑
actions: {
// context 参数具有和 Store 实例相同的属性和方法
asyncUpdateInfo(context: ActionContext<State, State>) {
setTimeout(() => {
context.commit("CHANGE_INFO_NAME")
}, 1000)
}
}
})
组件调用:
<script setup lang="ts">
import { useStore } from 'vuex'
const store = useStore()
const change = () => {
// 触发 Mutation (同步)
// store.commit("CHANGE_INFO_NAME")
// 触发 Action (异步)
store.dispatch("asyncUpdateInfo")
}
</script>
<template>
<div>
<p>姓名:{{ store.state.personalInfo.name }}</p>
<button @click="change">异步修改名称</button>
</div>
</template>
这是为了状态追踪。在 Vue Devtools 中,每当 Mutation 被提交,插件都会捕捉到前后的快照。如果是异步的,回调函数执行时 Mutation 已经结束,Devtools 无法追踪到状态到底是什么时候变化的,这会让调试变得极其困难。
| 特性 | Mutation | Action |
|---|---|---|
| 操作性质 | 同步操作 | 异步/同步均可 |
| 职责 | 唯一直接修改 State 的地方 | 提交 Mutation,不直接操作 State |
| 参数 | 第一个参数是 state | 第一个参数是 context 对象 |
| 调用方式 | commit('name') | dispatch('name') |
由于 Vuex 的状态是存储在内存中的,刷新页面后数据会丢失。
localStorage 或 sessionStorage。created)时,从本地取出数据重新还原到 Store。vuex-persistedstate 插件,可以自动完成持久化同步工作。