前言

在构建中大型 Vue 单页应用时,组件间的通信往往会变得复杂。Vuex 作为一个专为 Vue.js 应用程序开发的状态管理模式 + 库,采用集中式存储管理应用的所有组件的状态。本文将带你从核心概念到持久化方案,深度拆解 Vuex 的运行机制。

一、 为什么需要 Vuex?

1. 核心概念

Vuex 采用全局单例模式,将组件的共享状态抽取出来进行管理。它解决了以下两大痛点:

  • 多视图依赖同一状态:如用户信息在头部、侧边栏、个人中心都需要显示。
  • 不同视图的行为需要修改同一状态:如购物车在不同页面进行增删改查。

2. 单向数据流约束

Vuex 规定:组件可以读取 State,但严禁直接修改 State。这种约束确保了状态变更的可预测性和可追溯性。


二、 五大核心模块

1. State(全局仓库)

存储数据的唯一数据源,类似于组件的 data,只可以读,不能进行写操作。

2. Getters(加工厂)

有些时候我们需要对获取的数据进行加工,获取数据的一部分或者某些属性,而不是直接获取state中的数据时,这时候可以通过getter定义函数,返回对应的数据。

3. Mutations(状态变更)

唯一能修改 State 的地方,在vue组件中可以通过commit触发修改函数。不过mutations里面的操作必须是同步的

4. Actions(异步中转)

用于处理异步逻辑(如 API 请求),通过提交 (commit) Mutation 来间接修改 State。

5. Modules(模块化)

当 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>

四、 核心面试题

1. 为什么 Mutation 必须是同步的?

这是为了状态追踪。在 Vue Devtools 中,每当 Mutation 被提交,插件都会捕捉到前后的快照。如果是异步的,回调函数执行时 Mutation 已经结束,Devtools 无法追踪到状态到底是什么时候变化的,这会让调试变得极其困难。

2. Mutation vs Action 有什么区别?

特性MutationAction
操作性质同步操作异步/同步均可
职责唯一直接修改 State 的地方提交 Mutation,不直接操作 State
参数第一个参数是 state第一个参数是 context 对象
调用方式commit('name')dispatch('name')

五、 状态持久化与存储

由于 Vuex 的状态是存储在内存中的,刷新页面后数据会丢失。

  • 解决方案:结合 localStoragesessionStorage
  • 手动实现:在 Mutation 变更状态时同步写入本地存储;在页面加载(App.vue 的 created)时,从本地取出数据重新还原到 Store。
  • 进阶工具:推荐使用 vuex-persistedstate 插件,可以自动完成持久化同步工作。
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com