Pinia 撤销!重做!

B站影视 内地电影 2025-11-13 12:02 1

摘要:作为Vue官方新一代状态管理库,Pinia用更简洁的语法、更完善的 TypeScript 支持,以及去除了 mutations 的“直接改 state”风格,迅速取代了 Vuex,成为 Vue2 / Vue3 项目的首选。

使用 Vue 的开发者,对 Pinia 一定不会陌生。

作为 Vue 官方新一代状态管理库,Pinia 用更简洁的语法、更完善的 TypeScript 支持,以及去除了 mutations 的“直接改 state”风格,迅速取代了 Vuex,成为 Vue2 / Vue3 项目的首选。

然而,状态管理越集中,用户就越容易“手滑”——一不小心把表单清空、把配置覆盖、把画布误删。

此时,如果像 Photoshop 那样 Ctrl + Z 就能撤销,该多好?

这正是本文主角 pinia-undo 的价值所在:给任何 Pinia Store 一键加上“时间旅行”能力。

pinia-undo 是一个开箱即用的 Pinia 插件,它会在你的 Store 里自动注入:

undo – 撤销到上一状态redo – 重做刚才被撤销的变更history – 只读的历史栈,方便调试或显示“可撤销步数”零侵入:不改动你原有的 state / action可配置:想忽略某些字段?想禁用历史?想自定义序列化?都支持轻量化:仅 1 个依赖,gzip 后 兼容 Vue2 & Vue3:只要 Pinia 能跑,它就能跑

1. 安装

pnpm add pinia-undo# 或 npm / yarn

2. 注册插件

// main.tsimport { createPinia } from 'pinia'import { PiniaUndo } from 'pinia-undo'const pinia = createPiniapinia.use(PiniaUndo) // 一行代码,全局生效app.use(pinia)

3. 像平常一样写 Store

// stores/counter.tsexport const useCounter = defineStore('counter', { state: => ({ count: 10, name: 'Pinia' }), actions: { inc { this.count++ }, dec { this.count-- } }})

4. 模板里直接调用

提示:undo / redo 在栈顶/栈底会自动空操作,不会产生异常;你也可以通过 canUndo / canRedo 禁用按钮。

① 忽略敏感字段

有些字段(如 loading、updatedAt)不需要进入历史:

export const useForm = defineStore('form', { state: => ({ name: '', age: 0, loading: false }), // 告诉插件:别管 loading undo: { omit: ['loading'] }})

② 临时关闭历史

某些批处理操作想一次性提交,不想生成中间态:

export const useCanvas = defineStore('canvas', { undo: { disable: false }, // 默认开启 actions: { batchUpdate(list) { this.$patch((state) => { // 先关历史 this.$pinia.state.value.canvas.__UNDO_DISABLE = true list.forEach((op) => { /* 大量修改 */ }) // 再开历史 this.$pinia.state.value.canvas.__UNDO_DISABLE = false }) } }})

③ 自定义序列化

当 state 里包含 Map、Set、Dayjs 等不可 JSON 直接序列化的对象时:

import devalue from '@nuxt/devalue'export const useAdvanced = defineStore('advanced', { undo: { serializer: { serialize: devalue, deserialize: (str) => eval(`(${str})`) // devalue 逆向 } }})问题回答兼容 Pinia 2 吗?✅ 实测 Pinia 2.0+ 无问题支持 SSR 吗?✅ 历史栈保存在客户端,不影响服务端渲染内存会不会爆?默认保留 100 步,可自己裁剪 history 数组能同时监听多个 Store 吗?插件全局注册后,所有 Store 都自动拥有 undo/redo

状态管理给了 Vue 应用“单一数据源”的便利,也带来了“一错全错”的风险。

来源:不秃头程序员

相关推荐