Skip to content

历史记录与撤销重做 (HistoryPlugin)

createHistoryPlugin 基于纯快照栈实现完整的操作历史管理,支持 Ctrl+Z 撤销 / Ctrl+Y 重做 键盘快捷键,以及跳转到任意历史步骤的时间旅行功能。

快速上手

typescript
import { createHistoryPlugin } from '@yh-ui/flow'

onMounted(() => {
  // 1. 创建并安装插件
  const plugin = createHistoryPlugin({
    maxHistory: 100, // 最多保存 100 步历史
    enableKeyboard: true, // 启用 Ctrl+Z / Ctrl+Y 快捷键
    onHistoryChange: (canUndo, canRedo, length) => {
      // 根据状态更新 UI(按钮禁/启用)
    }
  })
  flowRef.value?.usePlugin(plugin)

  // 2. 插件安装后,在关键操作时机手动保存快照
  //    (推荐:精确控制历史粒度,性能最优)
})

// 3. 在合适的时机调用(拖拽结束 / 连线创建 / 删除等)
const handleDragEnd = () => flowRef.value?.saveSnapshot?.('拖动节点')

// 4. 撤销/重做(也可以直接按 Ctrl+Z / Ctrl+Y)
const undo = () => flowRef.value?.undo?.()
const redo = () => flowRef.value?.redo?.()

IMPORTANT

saveSnapshotundoredo 等方法是在 usePlugin 安装插件后 动态挂载到 flowRef.value 上的。 因此必须在 onMounted 后才能调用这些方法(组件 ref 及插件均已就绪)。

基础用法演示

步骤: 0
📦 拖动我!
⚙️ 再拖我!
💡 拖动节点 → 点击"保存快照" → 再点击撤销
撤销/重做 — 保存快照后可撤销/重做节点位置

API

HistoryPluginOptions

属性类型默认值说明
enabledbooleantrue是否启用插件
maxHistorynumber100最大历史记录步数(超出则自动丢弃最旧步骤)
enableKeyboardbooleantrue是否注册 Ctrl+Z/Y 键盘快捷键(全局 window 级)
onHistoryChange(canUndo, canRedo, length) => void历史变化时的回调,用于更新按钮状态

插件安装后的 FlowInstance 扩展方法

通过 flowRef.value?.usePlugin(plugin) 安装后,以下方法/属性自动挂载到 flowRef.value

方法/属性类型说明
undo()() => void撤销到上一快照
redo()() => void重做到下一快照
saveSnapshot(desc?)(description?: string) => void手动保存当前 nodes + edges 快照
clearHistory()() => void清空所有历史记录
jumpToStep(index)(index: number) => void跳转到指定历史步骤(时间旅行)
getHistory()() => FlowHistorySnapshot[]获取完整历史列表
canUndoRef<boolean>是否可撤销(响应式)
canRedoRef<boolean>是否可重做(响应式)
historyLengthRef<number>当前历史条数(响应式)

FlowHistorySnapshot 类型

typescript
interface FlowHistorySnapshot {
  nodes: Node[]
  edges: Edge[]
  timestamp: number
  description?: string
}

键盘快捷键

快捷键说明
Ctrl + Z / ⌘ + Z撤销
Ctrl + Y / ⌘ + Y重做
Ctrl + Shift + Z / ⌘ + ⇧ + Z重做(macOS 兼容)

最佳实践

TIP

不推荐开启 autoCapture(自动捕获所有变化),建议在业务操作的关键时机手动调用 saveSnapshot

typescript
// ✅ 推荐:在关键时机手动保存,精确控制历史粒度
flowRef.value?.on('node:dragend', () => flowRef.value?.saveSnapshot?.('拖动节点'))

// 连线创建后保存
// 删除操作前保存
// 用户手动点击"保存"按钮时保存

下一步

Released under the MIT License.