《Pinia 从入门到精通》Vue 3 官方状态管理 -- 基础入门篇

《Pinia 从入门到精通》Vue 3 官方状态管理 – 基础入门篇
《Pinia 从入门到精通》Vue 3 官方状态管理 – 进阶使用篇
《Pinia 从入门到精通》Vue 3 官方状态管理 – 插件扩展篇

为什么选择 Pinia?

1.1 背景介绍

Vuex 是 Vue 2 时代的官方状态管理库,但到了 Vue 3,Pinia 成为了 Vue 官方推荐的新一代状态管理解决方案。Pinia 的设计理念更贴近 Vue 3 的 Composition API,同时解决了 Vuex 中的一些设计痛点。

1.2 Vuex 的痛点(对比说明)

问题Vuex 表现Pinia 改进
API 复杂四个概念:state, mutation, action, getter仅需 state, getter, action,简洁直观
类型支持差TypeScript 体验差,类型推导复杂TS 完善支持,store 类型自动推导
严格模式限制mutation 强制同步,异步处理不直观action 中自由处理异步逻辑
模块嵌套繁琐多模块配置臃肿、调试困难每个 store 独立定义、组合灵活

1.3 Pinia 的优势

  • 📦 极简 API:你甚至可以用纯 JavaScript 写出 Vuex 的一半代码量
  • ⚙️ 完美支持 TypeScript:无须手动类型推导
  • 🚀 原生支持 Devtools,调试体验极佳
  • 🧩 插件机制灵活,生态成熟
  • 🌱 无需注册、按需使用,天然模块化设计

1.4 使用场景

Pinia 适用于所有 Vue 3 项目,尤其推荐在以下场景中使用:

  • 中大型项目,状态多、模块复杂
  • 需要 SSR 或 Nuxt 支持
  • 强类型开发团队,希望完善 TS 体验
  • 希望未来迁移方便,避免被 Vuex 设计束缚

好的,接下来我们将从安装 Pinia 开始,快速构建第一个 Store,并在 Vue 组件中使用它。


安装与快速上手

将带你完成以下目标:

  • 安装并配置 Pinia
  • 创建第一个 Store
  • 在组件中使用 State、Getter、Action
  • 初识 DevTools 与响应式调试

2.1 安装 Pinia

在 Vue 3 项目中安装 Pinia 非常简单:

npm install pinia
# 或
yarn add pinia
# 或
pnpm add pinia

2.2 在项目中注册 Pinia

以 Vite + Vue 3 项目为例,在 main.tsmain.js 中注册 Pinia:

// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp(App)
app.use(createPinia()) // 注册 Pinia
app.mount('#app')

2.3 创建第一个 Store

Pinia 中的 Store 是一个函数,通常我们放在 stores 文件夹下,每个 Store 文件代表一个独立模块。

// stores/counter.ts
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
    name: 'Pinia Demo'
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++
    },
    async fetchCountFromServer() {
      const result = await fetch('/api/count').then(res => res.json())
      this.count = result.count
    }
  }
})

2.4 在组件中使用 Store

我们在组件中使用 Store 的方式如下,注意 useCounterStore() 是一个函数,必须在 setup() 中调用:

<script setup lang="ts">
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()

function handleClick() {
  counter.increment()
}
</script>

<template>
  <div>
    <p>当前计数:{{ counter.count }}</p>
    <p>计数翻倍:{{ counter.doubleCount }}</p>
    <button @click="handleClick">+1</button>
  </div>
</template>

2.5 使用 DevTools 调试

Pinia 默认集成了 Vue DevTools。打开浏览器的开发者工具,切换到 “Pinia” 标签页:

  • 可实时查看 Store 中的 state
  • 支持时间旅行(Time-travel Debugging)
  • 可跟踪每一次 action 的调用和参数

2.6 快速回顾

名称说明
state存储响应式状态
getter计算属性,依赖 state,具缓存能力
action可执行逻辑(同步/异步),可以修改 state
defineStore定义一个 Store 函数
useXXXStore在组件中访问 Store,命名建议以 use 开头

✅ 小结

通过本章,你已经完成了从安装、配置、到创建并使用第一个 Pinia Store 的全过程。你应该已经能够在项目中灵活使用 state、getter 与 action,并通过 DevTools 进行调试。


好的,以下是第三章:核心概念解析的完整内容。我们将深入理解 Pinia 的核心组成部分,并结合实用示例与图示进行讲解,为后续进阶打下坚实基础。


核心概念解析 —— State、Getter、Action 深入理解

Pinia 是围绕三个核心概念构建的:StateGetterAction,这三者构成了所有 Store 的基石。


3.1 State —— 响应式数据源

✅ 定义方式

defineStore 中通过 state: () => ({}) 返回一个对象,即为该 Store 的状态树。

state: () => ({
  count: 0,
  userInfo: { name: 'Alice', age: 25 }
})
✅ 特点
  • 是响应式的(由 reactive 封装)
  • 可直接在组件中解构使用
  • 会被持久化插件等作为数据源操作
📌 使用建议
  • 状态初始值应明确,不使用 undefined
  • 尽量避免嵌套过深(会增加调试成本)

3.2 Getter —— 派生计算属性

✅ 定义方式

类似 Vue 的 computed 属性,依赖 State 自动更新,具备缓存能力。

getters: {
  doubleCount: (state) => state.count * 2,
  userSummary: (state) => `${state.userInfo.name} (${state.userInfo.age})`
}
✅ 特点
  • Getter 本质是 computed
  • 可以使用 this 访问其他 getter 和 state
getters: {
  doubleCount: (state) => state.count * 2,
  tripleCount() {
    return this.doubleCount + this.count
  }
}
📌 使用建议
  • 用于展示层逻辑,避免副作用(不要在 getter 中修改 state)
  • 可以将复杂的 UI 显示逻辑移入 getter,保持组件简洁

3.3 Action —— 方法逻辑封装

✅ 定义方式

类似 Vue 的 methods,用于封装业务逻辑。支持异步、可直接修改 state。

actions: {
  increment() {
    this.count++
  },
  async loadUser() {
    const data = await fetch('/api/user').then(res => res.json())
    this.userInfo = data
  }
}
✅ 特点
  • 可以包含异步逻辑(使用 async/await)
  • 可组合调用其他 actions
  • 可接收参数
actions: {
  updateUserName(name: string) {
    this.userInfo.name = name
  }
}
📌 使用建议
  • 所有数据修改逻辑应封装到 Action 中,保持一致性
  • 异步请求、表单提交、事件处理等建议全部写在 Action 中

3.4 示例整合

// stores/user.ts
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    name: 'Alice',
    age: 25
  }),
  getters: {
    summary: (state) => `${state.name}, 年龄 ${state.age}`
  },
  actions: {
    setName(newName: string) {
      this.name = newName
    },
    async fetchUser() {
      const data = await fetch('/api/user').then(res => res.json())
      this.name = data.name
      this.age = data.age
    }
  }
})

组件中使用:

<script setup lang="ts">
import { useUserStore } from '@/stores/user'

const userStore = useUserStore()

function changeName() {
  userStore.setName('Bob')
}
</script>

<template>
  <div>
    <p>{{ userStore.summary }}</p>
    <button @click="changeName">修改名字</button>
  </div>
</template>

✅ 小结

概念本质功能类比 Vue 中
Statereactive存储响应式数据data
Gettercomputed派生属性、自动缓存computed
Action普通函数/方法封装业务逻辑,支持异步、状态更新等methods

理解这三者后,你就掌握了 Pinia 的全部运行机制。它不再区分 mutation 与 action,让状态管理更加直观、自由。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值