欢迎光临
我们一直在努力

《Vue3 从入门到大神12篇》组件通信全景图(下)—— Vuex 到 Pinia 的华丽转身

前言

在前一篇文章中,我们明确了:

Event Bus 已死,Props / Emit / Provide-Inject 各有边界。

但还有一个问题没有解决:

❓ 真正的全局状态应该放在哪里?

Vue2 时代,答案是 Vuex。

Vue3 时代,官方给出的答案是:

✅ Pinia

这一篇,我们就来讲清楚:

  • Pinia 到底是什么?

  • 它如何取代 Vuex?

  • State / Getter / Action 怎么用?

  • 为什么它更适合 Composition API?


一、Vuex 的历史地位与痛点

1️⃣ Vuex 解决了什么问题?

✅ 集中式状态管理

✅ 可预测的数据流

✅ DevTools 支持


2️⃣ 但 Vuex 也有明显痛点

痛点

说明

概念太多

State / Getter / Mutation / Action

修改状态繁琐

必须 commit mutation

TypeScript 支持差

类型推导极其痛苦

代码冗长

一个简单的状态改动要写很多样板代码

📌 一句话总结:

Vuex 是为 Vue2 设计的,不是为 Composition API 设计的。


二、Pinia 是什么?

官方定义:

Pinia 是 Vue 的官方状态管理库,是 Vuex 的继任者。

它的设计目标非常明确:

  • ✅ 更简单

  • ✅ 更直观

  • ✅ 更好的 TypeScript 支持

  • ✅ 更贴合 Composition API


三、Pinia 核心概念(State / Getter / Action)

1️⃣ 定义一个 Store

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

export const useUserStore = defineStore('user', {
state: () => ({
name: 'Tom',
age: 18
}),
getters: {
doubleAge: (state) => state.age * 2
},
actions: {
growUp() {
this.age++
}
}
})

📌 对比 Vuex:

  • ❌ 没有 mutation

  • ✅ 只有 state / getter / action


四、在组件中使用 Pinia

1️⃣ 安装 Pinia

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

createApp(App)
.use(createPinia())
.mount('#app')


2️⃣ 使用 Store

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

const userStore = useUserStore()
</script>

<template>
<div>
<p>{{ userStore.name }}</p>
<p>{{ userStore.doubleAge }}</p>
<button @click="userStore.growUp">长大</button>
</div>
</template>

✅ 像使用普通对象一样使用状态


五、为什么 Pinia 能取代 Vuex?

1️⃣ 去掉了 Mutation

Vuex:

commit('increment')

Pinia:

store.increment()

📌 结论:

Mutation 是冗余设计。


2️⃣ 天然支持 TypeScript

const store = useUserStore()
store.age // ✅ 类型提示

Vuex 需要:

(this as any).$store.state.user.age


3️⃣ 与 Composition API 完美融合

export function useUser() {
const store = useUserStore()
return { …store }
}

✅ Pinia 本身就是 Composable 风格


六、Pinia 的响应式与解构

❌ 错误用法

const { name } = userStore

👉 会失去响应式


✅ 正确用法

import { storeToRefs } from 'pinia'

const { name } = storeToRefs(userStore)


七、Pinia 的高级能力

1️⃣ 模块化(天生支持)

stores/
├── user.ts
├── cart.ts
└── product.ts

✅ 无需 namespace


2️⃣ 组合式写法(推荐 ✅)

export const useUserStore = defineStore('user', () => {
const name = ref('Tom')
const age = ref(18)

const doubleAge = computed(() => age.value * 2)

const growUp = () => age.value++

return {
name,
age,
doubleAge,
growUp
}
})

📌 这是 Pinia 的终极形态。


八、Pinia vs Vuex 对比总结

对比项

Vuex

Pinia

Mutation

TypeScript

Composition API

代码量

学习成本


九、面试高频问答

Q1:Pinia 为什么去掉 Mutation?

因为 Mutation 增加了不必要的复杂度。

Q2:Pinia 和 Vuex 能共存吗?

可以,但不推荐。

Q3:Pinia 是全局状态还是局部状态?

全局状态,但可按模块拆分。


十、总结

  • Vuex 已完成历史使命

  • Pinia 是 Vue3 状态管理的唯一官方答案

  • 更简洁、更类型安全、更 Composable

  • 新项目 100% 使用 Pinia


📢 下期预告

👉 第 13 篇:插槽(Slots)完全指南 —— 从匿名插槽到作用域插槽

赞(0)
未经允许不得转载:171主机测评 » 《Vue3 从入门到大神12篇》组件通信全景图(下)—— Vuex 到 Pinia 的华丽转身
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址