Skip to content

命令模式与撤销重做

vkedit 的所有元素操作(添加、删除、变换、属性更新)都通过命令对象执行。每个命令记录操作的正向和逆向逻辑,从而实现撤销重做。

命令模式原理

用户操作 -> 创建 Command -> host.executeCommand(cmd)

                          cmd.execute()    <- 执行正向操作

                          撤销栈.push(cmd)

撤销时:

host.undo() -> 撤销栈.pop() -> cmd.undo()  <- 执行逆向操作

                                重做栈.push(cmd)

重做时调用 cmd.redo()(默认实现为再次调用 execute())。

内置命令

所有命令继承自 BaseCommand,构造函数第一个参数都是 host: EditorHost

命令构造函数说明
AddElementCommand(host, element)添加元素
RemoveElementCommand(host, element)删除元素
TransformElementCommand(host, element, oldState, newState)变换元素
UpdatePropertyCommand(host, element, propertyPath, oldValue, newValue)更新属性
BatchCommand(host, commands?, description?)批量命令
AlignElementsCommand(host, alignment, elementIds)对齐元素
DistributeElementsCommand(host, direction, elementIds)分布元素
ChangeLayerOrderCommand(host, elementId, direction)改变图层顺序
ClearSelectionCommand(host)清除选择

执行命令

typescript
import { AddElementCommand } from 'vkedit'

// 通过 ElementManagerPlugin 创建元素实例
const elementManager = host.getPlugin('element-manager-plugin')
const element = elementManager.createElement('rect')
element.xmm = 10
element.ymm = 10
element.wmm = 50
element.hmm = 30

// 执行命令
host.executeCommand(new AddElementCommand(host, element))

撤销与重做

typescript
// 撤销上一步操作
host.undo()

// 重做被撤销的操作
host.redo()

撤销/重做状态

通过监听 command:executedcommand:undonecommand:redone 事件感知命令栈变化。这三个事件在 host.executeCommand()host.undo()host.redo() 时分别触发。

批量命令

将多个操作组合为一个原子操作,撤销时按逆序回滚:

typescript
import { BatchCommand, AddElementCommand } from 'vkedit'

const commands = [
  new AddElementCommand(host, rectElement),
  new AddElementCommand(host, textElement),
]

// 执行批量命令(一次操作,一次撤销)
host.executeCommand(new BatchCommand(host, commands, '批量添加'))

也可逐步添加:

typescript
const batch = new BatchCommand(host)
batch.addCommand(new AddElementCommand(host, rectElement))
batch.addCommand(new AddElementCommand(host, textElement))
host.executeCommand(batch)

批量操作场景

拖拽创建多个元素、导入 JSON 文件时批量添加元素、一键对齐多个元素 -- 这些场景都应使用 BatchCommand。

下一步

基于 MIT 许可发布