这几天看了看Pinia,学习方向可以串成一条很清晰的线:先知道 Pinia 是干什么的,再学会怎么定义Store,然后理解 Store 实例能做什么,最后把数据持久化落地。这样学习时不会觉得知识点零散,复习时也更容易讲清楚前后关系。
一、什么是 Pinia,为什么 Vue项目更常用它
Pinia 是 Vue 官方推荐的状态管理库,可以把多个组件需要共享的数据抽出来统一管理。
它解决的不是"某个组件内部的数据怎么写",而是下面这些更典型的问题:
-
两个兄弟组件要访问同一份数据
-
一个组件改了数据,别的组件要同步更新
-
某些状态希望跨页面、跨组件长期存在
-
业务逻辑不想分散在很多组件里
和早期的Vuex相比,Pinia 的优势很明显:
-
API 更简洁
-
对 TypeScript 更友好
-
选项式和组合式两种写法都支持
-
可以直接使用 Vue 3 的响应式能力
所以在 Vue 3 里,Pinia 更像是"更轻、更自然的全局状态管理方案"。
二、Pinia 的使用起点:先创建实例,再挂载到应用
Pinia 不是写了 Store 就能直接用,它和路由、组件库一样,也要先注册到 Vue 应用中。
基本流程是:
-
导入createPinia
-
创建Pinia实例
-
通过app.use(Pinia) 挂载
如果项目里还要使用持久化插件,也是在这里统一注册。
这一步的本质要记住一句话:Store 能在任何组件里被使用,前提是整个应用先安装了 Pinia。
三、Pinia 最直观的价值:多个组件共享同一份状态
Pinia 最容易理解的场景,就是"组件 A 改数据,组件 B 立刻看到结果"。
比如一个计数器:
-
一个组件负责展示数字
-
另一个组件负责点击加一
如果不用 Pinia,这种共享通常要靠父子传值、事件通信,组件一多就开始绕。
用了 Pinia 之后,两个组件直接拿同一个 Store:
-
展示组件读取count
-
操作组件调用increment
这样状态从"组件私有"变成了"集中管理、按需使用"。这也是学 Pinia 时最先要建立的直觉。
四、Store 实例方法里最常用的是 $patch
$patch 是 Pinia 非常实用的一个实例方法,适合"批量修改状态"。
它有两种常见写法:
第一种是对象形式,适合直接覆盖部分字段:
TypeScript
store.$patch({
age: 18,
addr: '长沙'
})
第二种是函数形式,适合做连续修改或复杂逻辑:
TypeScript
store.$patch((state) => {
state.age++
state.addr = '上海'
})
这两种写法的区别可以这样记:
-
对象形式:像"批量赋值"
-
函数形式:像"进入状态内部做细节处理"
当你发现自己连续写很多 store.xxx = xxx 时,就该想到 $patch 了。
五、$reset、$subscribe、$onAction 分别解决什么问题
这三个方法经常一起出现,但它们负责的层次完全不同。
1. $reset:把 Store 恢复到初始状态
这个方法非常适合表单重置、退出登录、清空临时数据。
但有一个非常关键的点:选项式 Store 可以直接使用 $reset,组合式 Store 如果想重置,通常需要自己写一个重置函数。
所以它不是"所有 Store 都天然一样好用"的方法,这一点复习时一定要记住。
2. $subscribe:监听状态变化
它关注的是"状态改了什么"。
常见用途:
-
打印调试日志
-
做本地存储同步
-
观察某个 Store 的变更过程
当状态一变化就自动写入浏览器存储,这就是它最经典的应用场景之一。
3. $onAction:监听 Action 的执行过程
它关注的不是最终状态,而是"哪个 action 被调用了、何时开始、是否成功、是否失败"。
常见用途:
-
埋点统计
-
调试 action 调用链
-
统一记录业务行为
所以这两个监听方法要分清:
-
$subscribe盯的是"状态结果" -
$onAction盯的是"行为过程"
六、手动实现 Pinia 持久化,重点在"读取 + 监听 + 回写"
不用插件时,Pinia 一样可以自己实现持久化,思路并不复杂,关键是三步。
1. 初始化时读取本地存储
先从 **localStorage**里取出之前保存的数据。
2. 读取成功后回填到 Store
把拿到的数据通过 $patch 填回 Store,这样页面刷新后仍然能恢复之前的状态。
3. 订阅状态变化并再次写回
通过 $subscribe 监听 Store,一旦状态变化,就重新 setItem 到浏览器存储中。
这套思路非常值得掌握,因为它说明了持久化的本质:
Pinia 本身只负责内存中的响应式状态,真正的"持久保存"要靠浏览器存储机制配合。
七、Pinia 持久化插件的优势:把重复工作收起来
手动持久化能学到底层思路,但写多了会发现它有重复劳动:
-
每个 Store 都要自己读
-
每个 Store 都要自己订阅
-
每个 Store 都要自己处理序列化
这时候插件的价值就出来了。
先在项目入口安装插件,再在具体 Store 中开启持久化配置,就能把很多样板代码省掉。
这类插件的优势主要有三点:
-
使用成本低
-
配置集中
-
多个 Store 更容易统一管理
八、持久化插件不只是 persist: true,还可以细配
很多人第一次接触插件时,只记住一句话:persist: true。
但更实用的部分其实是高级配置。
常见可配项包括:
-
key:自定义存储键名 -
storage:决定存到localStorage还是sessionStorage -
pick:只持久化指定字段 -
omit:排除某些字段不持久化 -
serializer:自定义序列化与反序列化逻辑
这说明插件不是简单的开关,而是"在统一机制上允许定制"。
比如:
-
想让数据关掉浏览器就清空,可以用
sessionStorage -
想只保存用户名,不保存其他内容,可以用
pick -
想做简单编码处理,可以自定义
serializer
这也是为什么插件方案更适合真实项目,而不只是练习项目。
九、把这次 Pinia 学习串成一张复习地图
这次内容如果只记零散概念,很快会混。更好的方式是按下面这条线去复习:
-
Pinia 是做全局状态管理的
-
使用前要先创建并挂载 Pinia 实例
-
它最直接的价值是跨组件共享状态
-
定义 Store 有两种主流方式:选项式 API 和组合式 API
-
Store 不只是放数据,还能放 actions 和 getters
-
$patch适合批量修改状态 -
$reset负责重置,选项式 Store 更直接 -
$subscribe监听状态变化 -
$onAction监听行为执行过程 -
手动持久化的核心是读取、回填、订阅、回写
-
插件持久化的核心是统一配置和减少重复代码
-
真正掌握 Pinia,不是会写一个 Store,而是知道"状态定义、状态修改、状态监听、状态持久化"这一整条链路
我认为这十二点是pinia入门的重中之重,理解弄懂这十二点才能更好的推进后面知识点的学习。