文章目录

Vue 状态管理:Vuex 与 Pinia

发布于 2026-04-06 21:12:07 · 浏览 265 次 · 评论 0 条

Vue 状态管理:Vuex 与 Pinia


阶段一:评估需求与确定技术栈

  1. 核对 当前项目使用的 Vue 框架版本。Vue 3 项目默认推荐 Pinia;Vue 2 项目若未启用 Composition API 组合式 API,继续使用 Vuex 3.x 即可。
  2. 评估 跨组件通信的复杂度。仅涉及简单父子传值或基础配置读取时,直接使用 Vue 内置的 provide 提供与 inject 注入;涉及复杂业务流、全局拦截或大型团队协作时,引入 独立状态管理库。
  3. 查阅 团队现有技术规范。若项目已存在大量 Vuex 模块且维护成本可控,保留 现有架构;新建模块或重构旧代码时,优先选择 Pinia,因其原生支持类型推断、打包体积更小且无需嵌套 Mutation 修改数据。
特性维度 Vuex Pinia
核心架构 单一全局 Store 树 + 嵌套 Module 模块 扁平化独立 Store 实例设计
数据修改路径 强制通过 Mutation 同步提交,Action 处理异步请求 直接在 Action 中修改,彻底取消 Mutation 概念
类型推断支持 需额外安装插件或手动定义复杂接口声明 完整支持 TypeScript,函数调用即可自动推导类型
核心打包体积 约 11 KB(Gzip 压缩后) 约 1 KB(Gzip 压缩后)

阶段二:安装与初始化项目

  1. 打开 终端或命令行窗口,切换 至前端项目根目录。
  2. 执行 包管理器安装命令。若确定使用 Pinia,输入 npm install pinia;若维持 Vuex 体系,输入 npm install vuex@next 以适配 Vue 3。
  3. 创建 状态库入口目录。在项目 src 文件夹下 新建 名为 store 的目录,并在其内部 生成 文件 index.js。
  4. 编写 根应用挂载逻辑。打开 src/main.js,导入 状态库创建函数并 注册 至 Vue 实例。以 Pinia 为例:
    
    import { createApp } from 'vue'
    import { createPinia } from 'pinia'
    import App from './App.vue'

const app = createApp(App)
const pinia = createPinia()

app.use(pinia)
app.mount('#app')

若使用 `Vuex`,需替换为 `import { createStore } from 'vuex'`,并将 `createPinia()` 替换为 `createStore({ state: {}, mutations: {} })`,**调用** `app.use()` 传入实例对象。

---

## 阶段三:编写状态管理核心逻辑

1. **定义** 独立状态模块。进入 `src/store` 目录,**新建** 业务文件 `userStore.js`。
2. **初始化** Store 实例结构。`Pinia` 采用组合式函数 API,**调用** `defineStore` 并传入唯一标识符 `id`、响应式状态 `state` 与操作方法:
```javascript
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useUserStore = defineStore('user', () => {
  // 定义响应式状态
  const userInfo = ref({ name: '', token: '', role: '' })

  // 定义派生状态(计算属性)
  const isLoggedIn = computed(() => Boolean(userInfo.value.token))

  // 定义同步与异步操作
  async function fetchProfile() {
    const response = await fetch('/api/me')
    const data = await response.json()
    userInfo.value = data
  }

  function clearSession() {
    userInfo.value = { name: '', token: '', role: '' }
  }

  return { userInfo, isLoggedIn, fetchProfile, clearSession }
})
  1. 编写 Vuex 等效实现。若项目强制使用 Vuex,必须严格拆分同步与异步层:
    
    import { createStore } from 'vuex'

export const userModule = {
namespaced: true,
state: () => ({
userInfo: { name: '', token: '' }
}),
mutations: {
updateProfile(state, payload) {
state.userInfo = payload
}
},
actions: {
async fetchProfile({ commit }) {
const res = await fetch('/api/me')
const data = await res.json()
commit('updateProfile', data)
}
},
getters: {
isLoggedIn: (state) => !!state.userInfo.token
}
}

4. **合并** 模块至主入口。在 `src/store/index.js` 中 **导入** 刚定义的模块,**导出** 统一状态树配置。

---

## 阶段四:在组件中调用与监听状态

1. **打开** 需要消费全局状态的 Vue 单文件组件(如 `src/views/Home.vue`)。
2. **导入** 状态函数。在 `<script setup>` 标签顶部 **添加** 引用语句:`import { useUserStore } from '@/store/userStore.js'`。
3. **实例化** Store 对象。在组件顶层作用域内 **调用** 函数并 **接收** 返回值:`const userStore = useUserStore()`。注意:必须在 `setup` 语法环境或组件生命周期内调用,**禁止** 在外部 JS 文件中全局调用。
4. **读取** 响应式数据。在模板 `{{ }}` 插值表达式中 **直接使用** `userStore.userInfo.name`;在 `<script>` 逻辑中 **绑定** `userStore.isLoggedIn` 控制条件渲染。
5. **触发** 状态更新。为交互元素(如按钮或表单)**绑定** 事件回调,**执行** 异步请求方法:`userStore.fetchProfile()`。若使用 `Vuex`,需通过 `import { useStore } from 'vuex'` 获取根实例,并 **调用** `store.dispatch('user/fetchProfile')`。
6. **监听** 数据流转。在 `<script setup>` 中 **引入** Vue 的监听器:`import { watch } from 'vue'`,并 **配置** 响应式观测:
```javascript
watch(() => userStore.isLoggedIn, (isLogged, wasLogged) => {
  if (isLogged && !wasLogged) {
    // 执行登录成功后的路由跳转或埋点逻辑
  }
})

阶段五:调试追踪与持久化配置

  1. 启用 官方浏览器调试工具。访问 Chrome 或 Edge 扩展商店,搜索 Vue.js devtools 并完成插件安装。
  2. 捕获 状态变更轨迹。刷新目标页面,按 F12 调出开发者面板,切换 至 Vue 专属选项卡。在左侧面板 点击 Pinia 或 Vuex 分类,右侧视图将渲染当前全局状态快照树。
  3. 回溯 历史数据版本。在插件时间轴控件上 点击 任意灰色节点,验证 页面数据是否精准还原至该节点记录时刻。测试完毕后,拖动 滑块至最右侧恢复实时状态。
  4. 拆分 巨型状态文件。当单个模块逻辑行数突破 300 行时,采用 组合策略将购物车、权限、主题等子状态抽离为独立 .js 文件,并在 index.js 中统一聚合导出。
  5. 挂载 本地持久化插件。若需在页面刷新后保留登录态或用户偏好,运行 npm install pinia-plugin-persistedstate,修改 src/main.js 注册流程:
    
    import { createPinia } from 'pinia'
    import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)


在状态定义中 **附加** 配置项,于 `defineStore` 返回值平级 **添加** `__persist: true` 或完整对象 `{ key: 'app-user', storage: sessionStorage }`,**指定** 浏览器存储引擎。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文