再来聊聊,Vue3 项目中 Pinia 的替代方案

作者:前端布鲁伊日期:2025/11/23

想获取更多2025年最新前端场景题可以看这里fe.ecool.fun

大家好,我是刘布斯。

之前转载了一篇文章Vue 项目不要再用 Pinia 了,先不可否认,这文章有点标题党的意思。但这篇文章的主要观点是说,在中小项目里,用 Vue 3 自带的组合式 API(reactive / ref)来管状态,很多时候比硬上 Pinia 要香。

好家伙,评论区一下就热闹了,总结起来是:“Pinia 多好用,你肯定是没用明白 Pinia”

说实话,我确实有点意外。

我先摆明态度:Pinia 是个非常优秀的状态管理库。 尤雨溪团队亲自操刀,API 设计简洁,TS 支持完美,插件系统灵活,Devtools 体验丝滑。这一点,没人能否认。

但我的核心观点是:优秀,不代表“所有场景都必须上”。

我发现现在很多团队,尤其是从 Vue 2 刚迁到 Vue 3 不久的,存在一种很强的 “状态管理惯性”

什么意思?

在 Vue 2 + Options API 的时代,组件(Component)和状态(State)是“隔离”的。data 里的状态天生就是“内向”的,组件一销毁,状态就没了。跨组件通信、全局状态共享,你怎么办?你没得选,你必须上 Vuex。Vuex 就像一个“中央空调”,你不用它,别的房间(组件)就享受不到冷气(状态)。

所以,Vue 2 时代养成了我们的思维定式:做项目 = Vue 全家桶 = Vue + Vue Router + Vuex。

到了 Vue 3,Vuex 退位,Pinia 继任。于是大家理所当然地把公式换成了:做项目 = Vue 3 + Vue Router + Pinia。

启动一个新项目,npm create vue@latest,一路 yes 下来,Pinia 就装好了。然后就开始 defineStore

但大家好像都忽略了 Vue 3 最大的革命性变化——组合式 API (Composition API) 本身,就已经是一种强大的状态管理模式了。

defineStore 帮我们做了什么?

还是用那篇文章中的例子,做一个最简单的“用户状态管理”,两种方式有什么区别。

1. Pinia 的方式: 你得先在 stores/user.ts 里:

1import { defineStore } from'pinia'
2import { ref, computed } from'vue'
3
4exportconst useUserStore = defineStore('user', () => {
5// State
6const token = ref(null)
7const userProfile = ref(null)
8
9// Getters
10const isLoggedIn = computed(() => !!token.value)
11
12// Actions
13function login(data) {
14    token.value = data.token
15    userProfile.value = data.profile
16    // ...  localstorage
17  }
18
19function logout() {
20    token.value = null
21    userProfile.value = null
22    // ...  localstorage
23  }
24
25return { token, userProfile, isLoggedIn, login, logout }
26})
27

然后在组件里 useUserStore()

2. 组合式 API 的方式: 你在 stores/user.ts (对,你也可以叫 stores 目录,这只是个文件夹):

1import { ref, computed, reactive } from'vue'
2
3// 以前我们用 reactive,这里用 ref/computed 模拟 Pinia 的结构
4const token = ref(null)
5const userProfile = ref(null)
6
7const isLoggedIn = computed(() => !!token.value)
8
9function login(data) {
10  token.value = data.token
11  userProfile.value = data.profile
12// ...  localstorage
13}
14
15function logout() {
16  token.value = null
17  userProfile.value = null
18// ...  localstorage
19}
20
21// 导出一个 hook
22exportfunction useUser() {
23return { token, userProfile, isLoggedIn, login, logout }
24}
25

然后在组件里 useUser()


好了,你对比下这两段代码。

你发现了什么?

在第二种方式里,我只是删掉了 defineStore('user', ...) 那层“壳”,然后把导出的 useUserStore 改成了 useUser (叫什么都行)。

其他的逻辑,一模一样! 都是在用 refcomputed

Pinia 的 defineStore 在这个场景里,本质上就是帮你做了一件事:创建了一个跨组件共享的、响应式的单例。

但在 Vue 3 里,import 一个在模块顶层(module scope)定义的 refreactive 对象,它天生就是单例!它天生就是跨组件共享的!

那你可能会反问了:“那 Pinia 岂不是多此一举?”

不,它当然不是多此一举。它提供了 defineStore 这个“壳”,是为了给你带来额外的好处,最核心的就是:

  1. Devtools 集成:这是 Pinia 最大的杀手锏。你可以在时间轴上看到 action 的调用、state 的变更。
  2. 插件系统:比如实现数据持久化,Pinia 有现成的插件,defineStore 的时候配置一下就行。
  3. SSR 支持:在服务端渲染时,Pinia 能帮你处理好状态的序列化和“注水”(hydration)。
  4. 更严格的“心智模型” :它强制你区分 stategettersactions,让团队协作更规范。

Pinia的优势,你的项目真的需要吗?

我们再回到上篇文章的核心观点:

在一个中小型项目、独立开发、或者团队成员对组合式 API 都很熟练的场景下,上面 Pinia 提供的 4 个好处,你真的都需要吗?

  • Devtools:说实话,在我十多年的生涯里,除了在 Redux/Vuex 刚出来那会儿,为了调试复杂的异步流和中间件,会去用时间旅行。在绝大多数业务场景里,console.log 和 Vue Devtools 里自带的组件状态检查,已经解决了 99% 的问题。为了那 1% 的“可能”,去引入一个库,划算吗?
  • 插件系统(如持久化) :用组合式 API 怎么做持久化?太简单了。你封装的 useUser hook 里面,login 的时候加一行 localStorage.setItem,初始化 token 的时候加一行 localStorage.getItem。这不就是最原始、最可控的持久化吗?你需要为这么点功能,去学一个 Pinia 插件的 API 吗?
  • SSR:如果你的项目压根就不是 SSR,那这条对你无效。
  • 严格的心智模型:这是最大的“陷阱”。组合式 API 的核心思想就是“自由”。它允许你把 stateaction 放在一起,按“功能”去组织代码,而不是按“类型”(state/getter/action)去组织。defineStore 某种程度上,是又把我们拉回了 Vuex 的那种“分门别类”的思维里。

所以,“你会得到更少的心智负担”指的就是这个。

你不需要去记 defineStore 的 API,不需要去想“我这个逻辑是算 getter 还是 action”,你就是在写 JS/TS,你就是在写 function这难道不是一种解放吗?

什么叫“没用明白 Pinia”?

在我看来,恰恰相反。

把 Pinia 当成新时代的 Vuex,不分场景、启动项目就先装上,这才是“没用明白 Vue 3”。

如果没有明白 Vue 3 组合式 API 到底给了你多大的“自由”和“能力”,就可能继续用 Vue 2 的“保姆式”思维在写 Vue 3。

我想了几个场景,大家参考下:

  1. 场景一:个人项目、小团队敏捷开发、内部工具
  • 我的选择:100% 使用组合式 API。
  • 理由: 速度快,灵活,零依赖。我可以按功能拆分 useCounter.ts, useUser.ts, useCart.ts... 它们就是一堆 TS 模块,需要共享就在顶层定义 reactive,不需要就只导出函数。打包体积更小,心智负担为零。
  1. 场景二:大型企业级应用、多团队协作、需要强规范
  • 我的选择:我会倾向于使用 Pinia。
  • 理由: 这种项目,“规范”大于“灵活”。defineStore 提供的统一范式,能让不同水平的开发者(尤其是新人)写出风格更一致的代码。而且在这种复杂项目里,Devtools 的时间旅行和状态快照,在排查深层 Bug 时,确实能派上用场。
  1. 场景三:需要 SSR 的项目
  • 我的选择:用 Pinia。
  • 理由: 别重复造轮子。Pinia 对 SSR 状态处理得很好,自己搞一套组合式 API 的 SSR 状态同步,费时费力,不值得。

所以你看,并不是在全盘否定 Pinia,而是在呼吁大家 “按需选择”

不要因为“大家都用”或者“官方推荐”就去用。工具是死的,人是活的。Vue 3 给了我们一把更轻、更快的匕首(组合式 API),你为什么非要抱着那把很牛、但也很重的开山刀(Pinia)不放,连切个水果都要用它呢?

下次在项目里 npm install pinia 之前,先停 5 秒钟,问问自己:我这次,真的需要它吗?还是说,几个 refreactive 就能搞定了?

想明白这个问题,可能比你多刷 10 篇 Pinia 的教程都有用。

行了,今天就聊到这。


再来聊聊,Vue3 项目中 Pinia 的替代方案》 是转载文章,点击查看原文


相关推荐


2025.11.19 力扣每日一题
小白程序员成长日记2025/11/21

2154.将找到的值乘以2 这个题目比较简单,做的挺快的。 class Solution { public: int findFinalValue(vector<int>& nums, int original) { //1.对数组进行排序 sort(nums.begin(),nums.end()); //2.遍历排序后的数组 for (int num : nums) { //3.如果当前数字等于original


Windows开发:一场与指针的共舞,亦是超越它的征程
码事漫谈2025/11/19

当人们问“Windows开发导致指针吗?”或“Windows开发到底指针么?”,这背后其实是一个混合了技术困惑和职业好奇的复杂问题。简单来说,这个问题的内核是:Windows开发是否是一个整天与令人头疼的指针打交道的岗位? 答案是双重的:是的,深入理解指针是高级Windows开发的基石;但也不是,因为现代Windows开发已经在很大程度上帮助你管理指针,让你更专注于业务逻辑。 一、解码问题:什么是“Windows开发到底指针么?” 这个问题通常源于以下几点认知: 技术传说: C/C++是Win


rust语言,将JSON中的所有值以字符串形式存储到sqlite数据库中(逐行注释)
咸甜适中2025/11/18

主要功能实现: 所有json中数字转为字符串,保持精度不变巨大值 直接存储为字符串:3355446515156151516158.55125184845684值为列表:["egeggeg","gegeg",25.5] 存储为: ["egeggeg","gegeg","25.5"]值为字典:{"name":"小小","age":26} 存储为: {"name":"小小","age":"26"} 代码 use regex::Regex; use rusqlite::{Connection, Res


利用CMDB数据实现指标业务维度的动态扩展
可观测性用观测云2025/11/17

背景 很多客户已经建有 Prometheus/Zabbix 等采集方式,通常不会贸然替换 DataKit 进行直采,往往是通过 DataKit 去获取其它工具采集的结果。如 Prometheus remote write,Zabbix export 等。 为了增加不同数据类型的关联性,需要对已有的指标数据添加更多业务 TAG,如应用名,所属项目,部门等。为实现此类需求,需要能够获得原始的相关配置信息,如 CMDB 数据等。然后通过观测云 Pipeline 中的 refere_table() 方法


深入浅出 SQLSugar:快速掌握高效 .NET ORM 框架
q***2512025/11/16

SQLSugar 是一个高效、易用的 .NET ORM 框架,支持多种数据库(如 SQL Server、MySQL、PostgreSQL 等)。它提供了丰富的功能,包括 CRUD 操作、事务管理、动态表名、多表联查等,开发者可以通过简单的链式操作实现复杂的数据库逻辑。 本文将以完整的示例,详细介绍 SQLSugar 的安装、配置和功能使用,适用于 .NET Framework 和 .NET Core 项目。 一、SQLSugar简介 1. 什么是 SQLSugar? SQLSugar 是一个轻量


vscode编译C语言 | 在VSCode中配置编译环境与常见问题解决
epvikz_0732025/11/15

三十岁学编程|从零开始,如何在30岁起步学编程并成功转行许多人认为编程是年轻人的事情,尤其是到了三十岁,很多人会觉得自己已经错过了最佳学习的时机。然而,实际上三十岁学编程并非不可能,反而可能是一个崭新的开始。在这个信息化时代,编程能力已成为许多行业的基本技能,很多人通过自学编程成功转行,获得了新的职业发展机会。首先,学编程最重要的就是坚持和耐心。虽然编程看起来有些抽象,但通过系统的学习和实践,任何人都可以掌握基本的编程技能。比如,掌握Python或JavaScript等基础语言,它们不仅有着强大


用Microsoft Visual Studio Installer Projects 2022打包程序,同时安装VC++的运行库等
CE贝多芬2025/11/13

目录 一、安装插件 二、创建打包程序 在解决方案中新建打包项目 三、配置打包属性内容等 文件系统的各个文件夹 将输出程序打包进Application Folder 创建桌面快捷方式 创建卸载程序 给快捷方式创建图标 设置打包时的属性以及安装语言,安装位置等信息 四、打包 五、附录 六、附录二 一、安装插件 说明: Microsoft Visual Studio Installer Projects 2022 是微软官方提供的 Visual Studio


高德MCP服务接入
QD.Joker2025/11/12

创建一个agent,集成高德MCP工具 文章目录 一、安装依赖二、获取高德key三、代码实现 一、安装依赖 pip install openai pip install langchain (1.0版本以上) pip install langchain_mcp_adapters 二、获取高德key https://lbs.amap.com/api/mcp-server/create-project-and-key 三、代码实现 import asynci


XC7A200T-2FBG676I Xilinx AMD Artix-7 FPGA
XINVRY-FPGA2025/11/10

XC7A200T-2FBG676I 是 赛灵思 Xilinx AMD 推出的高性能低功耗 FPGA,隶属于 Artix-7 系列。该芯片基于 28nm 低功耗硅工艺,采用可扩展的 7 系架构,旨在在性能、功耗和成本之间实现最佳平衡。它主要面向高速数据采集、视频处理、通信系统、工业控制与嵌入式硬件加速等场合,适合那些需要较高逻辑容量和中高速信号处理能力的系统。 该芯片拥有约 215,360 个逻辑单元,包含约 33,650 个查找表(LUT)等效逻辑模块,内部集成大容量片上存储资源,总片上


Socket编程实战:从基础API到多线程服务器
violet-lz2025/11/8

一、Socket编程概述:网络通信的桥梁 Socket(套接字)是网络通信的端点,它提供了不同主机间进程通信的接口。在Linux系统中,Socket可以被视为一种特殊的文件描述符,通过标准的文件I/O操作来进行网络数据传输。 Socket编程的核心概念         通信域:确定通信的协议族和地址格式         套接字类型:定义通信的语义和特性         协议:指定具体的传输协议         地址:标识网络中的通信端点 学习Socket编程的重要性:      

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2025 聚合阅读