首页/新闻资讯/正文详情

craft.js 0.1.x 迁移指南:多选(Multiselect)机制下的 EditorState 与节点规则升级

发布时间:2026/9/25 5:44:15 来源:云帆数科 栏目:资讯中心
craft.js 0.1.x 迁移指南:多选(Multiselect)机制下的 EditorState 与节点规则升级
前端【免费下载链接】craft.js A React Framework for building extensible drag and drop page editors项目地址https://gitcode.com/gh_mirrors/cr/craft.js点击查看免费下载导读本文以 craft.js 官方迁移文档 site/docs/migrating/0.1.x.md 为主体系统梳理从 0.1.x 升级到 0.2.x 时由多选Multiselect功能引发的三处破坏性变更EditorState.events从单值NodeId变为集合SetNodeId、基于useEditor的状态收集方式需要改用.has()判断、User Component 的canMoveIn/canMoveOut规则参数从单个Node变为Node[]。阅读本文后你将能够准确识别旧代码中的迁移点并掌握与新事件模型及数组化规则签名对应的完整改造写法。背景为什么 0.2.x 引入了破坏性变更0.1.x 时代的 EditorState 一次只能表达一个“事件目标”当前被选中的节点、被拖拽的节点或被悬停的节点各自都只是一个NodeId。从 0.2.x 开始craft.js 引入了Multiselect多选能力允许用户同时框选多个节点并在一次拖拽中批量移动多个节点。多选使得事件模型必须从“单数”变成“复数”——同一个selected/dragged/hovered事件不再指向唯一节点。这一能力直接体现在核心包的类型定义中EditorEvents被定义为RecordNodeEventTypes, SetNodeIdpackages/core/src/interfaces/editor.ts事件类型仅有三种selected | dragged | hoveredpackages/core/src/interfaces/nodes.tsEditorState通过events: EditorEvents字段挂载这一集合模型packages/core/src/interfaces/editor.ts。因此凡是读取state.events的旧代码都必须同步升级否则类型检查与运行时行为都会出错。变更一EditorState.events 从 NodeId 变为 Set官方迁移文档给出了最直观的类型差异// 0.1.x type EditorState { ... // same as before events: NodeId; } // 0.2.x type EditorState { ... // same as before events: SetNodeId; }对应到当前仓库的源码实现这一签名不仅停留在类型层也贯穿了运行时状态更新逻辑。在 packages/core/src/editor/actions.ts 的setNodeEvent中可以看到先把state.events[eventType]中所有旧节点的事件标记清空state.nodes[id].events[eventType] false将state.events[eventType]重置为new Set()通过getNodesFromSelector解析目标节点支持idOnly/existOnly选项把解析出的 id 列表构造成SetNodeId后写回state.events[eventType]。也就是说events字段在 0.2.x 中始终是Set而不是数组或单个 id。仓库中的测试也验证了这一行为packages/core/src/editor/tests/actions.test.ts 用actions.setNodeEvent(selected, [node-a, node-b])同时选中两个节点并断言期望状态为events: { selected: new Set([node-a, node-b]) }。此外clearEvents()现在会一次性清空三类事件selected、hovered、dragged并重置放置指示器packages/core/src/editor/actions.ts这与集合模型的整体替换语义保持一致。升级要点小结维度0.1.x0.2.xstate.events.selectedNodeId字符串SetNodeId判断某节点是否被选中 node-id.has(node-id)多节点事件表达不支持一个Set同时容纳多个节点 id底层更新方式单值覆盖new Set()整体重建后写入变更二更新 useEditor 收集的状态值由于events变成了Set所有通过useEditor的 collector 函数从state.events收集值的代码都必须从等值比较改为has判断。官方迁移文档给出的对照如下// 0.1.x const { selected, hovered, dragged } useEditor(state ({ selected: state.events.selected some-node-id, hovered: state.events.hovered some-node-id, dragged: state.events.dragged some-node-id, })) // 0.2.x const { selected, hovered, dragged } useEditor(state ({ selected: state.events.selected.has(some-node-id), hovered: state.events.hovered.has(some-node-id), dragged: state.events.dragged.has(some-node-id) }))从源码结构看useEditor的 collector 机制没有变化它接受一个可选的 collector 函数EditorCollectorS内部通过useInternalEditor订阅 store把收集到的切片值作为返回值暴露给组件packages/core/src/hooks/useEditor.tsx。因此迁移成本完全集中在“读取events的方式”上useEditor本身的调用形态、返回的actions/query对象均无需调整。实操检查清单搜索代码中所有state.events.selected 、state.events.hovered 、state.events.dragged 形式的等值比较一律改为state.events.selected.has(...)等.has()调用若某个事件值被当作字符串使用如直接传给 action、拼进 key 等需要重新审视语义0.2.x 下事件值可能是多个节点的集合。变更三canMoveIn / canMoveOut 规则签名升级为 Node[]多选不仅影响状态读取还影响 User Component 的移动规则。在 0.2.x 中canMoveIn与canMoveOut的第一个参数从单个Node变为Node[]因为一次拖拽可能携带多个传入/移出的节点规则必须能对“整批”节点做判断。官方迁移文档给出的对照示例const Button () { return (...) } // 0.1.x Button.craft { rules: { canMoveIn: (incomingNode: Node, currentNode: Node, helpers: NodeHelpers) { return incomingNode.data.name Text; }, canMoveOut: (outgoingNode: Node, currentNode: Node, helpers: NodeHelpers) { return outgoingNode.data.name Text; } } } // 0.2.x Button.craft { rules: { canMoveIn: (incomingNodes: Node[], currentNode: Node, helpers: NodeHelpers) { return incomingNodes.every(incomingNode incomingNode.data.name Text) }, canMoveOut: (outgoingNodes: Node[], currentNOde: Node, helpers: NodeHelpers) { return outgoingNodes.every(outgoingNode outgoingNode.data.name Text) } } }当前仓库的NodeRules类型定义与此完全一致——数组是必选签名export type NodeRules { canDrag(node: Node, helpers: NodeHelpersType): boolean; canDrop(dropTarget: Node, self: Node, helpers: NodeHelpersType): boolean; canMoveIn(canMoveIn: Node[], self: Node, helpers: NodeHelpersType): boolean; canMoveOut(canMoveOut: Node[], self: Node, helpers: NodeHelpersType): boolean; };见 packages/core/src/interfaces/nodes.ts其中NodeHelpersType QueryCallbacksFortypeof QueryMethods[node]即查询方法的 node 维度集合packages/core/src/interfaces/nodes.ts。另外需要注意Button.craft.rules属于可选的PartialNodeRulespackages/core/src/interfaces/nodes.ts并非所有规则都必须实现但一旦实现canMoveIn/canMoveOut就必须使用数组签名。数组参数在底层如何被使用从源码调用链看canMoveIn的数组参数在拖放校验isDroppable中扮演关键角色。在 packages/core/src/editor/NodeHelpers.ts 中isDroppable(selector, onError?)会先把selector解析为一批目标节点newParentNode.rules.canMoveIn( targets.map((selector) selector.node), newParentNode, nodeHelpers )即targets.map(selector selector.node)得到的Node[]会原样传入canMoveIn这意味着若规则仅判断“单个节点是否符合条件”请使用.every()全部满足才放行或按需使用.some()任一满足即可放行多选拖拽时一次isDroppable校验会针对整批节点触发一次canMoveIn而不是逐个触发返回值仍为booleaninvariant会在返回false时抛出ERROR_MOVE_INCOMING_PARENT之类的错误并阻止放置。迁移操作建议先跑类型检查升级到 0.2.x 后先对使用state.events和rules的代码执行 TypeScript 编译编译器会直接标出所有NodeId/Node与SetNodeId/Node[]不兼容的位置这比手工搜索更可靠。集中替换事件读取将useEditor及其他访问state.events的 collector 统一改为.has()判断并注意selected/hovered/dragged三类事件都要覆盖。重写移动规则把canMoveIn/canMoveOut的单节点参数改为数组参数并用every/some表达“整批放行”或“存在即放行”的策略多选拖拽下建议先用every保持与旧行为一致的严格校验。验证多选交互迁移完成后通过actions.setNodeEvent或直接框选多个节点确认state.events.selected为包含多个 id 的Set且拖拽多个节点时canMoveIn收到的是完整的Node[]可参考 packages/core/src/editor/tests/actions.test.ts 的断言写法编写自己的单元测试。小结0.2.x 的多选能力是本次迁移的根本动因它把事件模型从“单节点”提升为“节点集合”相应地带来两处接口级变更events字段与canMoveIn/canMoveOut签名和一处调用级变更collector 改用.has()。按照本文给出的三张对照表与检查清单即可在不改变组件结构的前提下完成平滑迁移并充分使用多选拖拽带来的批量编辑能力。赞分享前端【免费下载链接】craft.js A React Framework for building extensible drag and drop page editors项目地址https://gitcode.com/gh_mirrors/cr/craft.js点击查看免费下载相关推荐VoltAgent 迁移指南从 0.1.x 到 1.x 再到 2.x 的完整升级路径与源码级解析VoltAgent 迁移指南从 0.1.x 到 1.x 再到 2.x 的完整升级路径与源码级解析 本文基于 VoltAgent 仓库中的官方迁移文档 migr人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音Semantica 跨会话记忆实战用 save() 与 load() 让 Agent 重启不失忆的完整指南Semantica 跨会话记忆实战用 save 与 load 让 Agent 重启不失忆的完整指南 多数 AI Agent 的上下文都活在进程内存里一重启人工智能大模型知识图谱RAGAI 可解释性后端MCP 服务3步解锁数据自由WeChatMsg让你的聊天记录真正属于你3步解锁数据自由WeChatMsg让你的聊天记录真正属于你 你是否曾有过这样的瞬间想找回三年前和好友的那段珍贵对话却发现微信的聊天记录早已消失无踪。那些深上一篇gh_mirrors/c4/c4项目持续部署自动发布与版本管理下一篇3步搞定Yuedu书源误删恢复回收站功能全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

拼团交易平台实战:用 DeepSeek 设计拼团 UI(需求拆解、提示词与代码落地)
拼团交易平台实战:用 DeepSeek 设计拼团 UI(需求拆解、提示词与代码落地)

文档教程后端 【免费下载链接】CodeGuide :books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、… · 2026/9/25 5:44:09

Interlaken协议详解:从虚拟通道到FPGA实现的芯片互联指南
Interlaken协议详解:从虚拟通道到FPGA实现的芯片互联指南

简介:面向芯片间高速互联与网络交换领域工程师的Interlaken协议学习教案。该协议支持多通道并行传输,带宽可达150Gbps,相比XAUI与SPI具备更优的带宽扩展性和流控机制。演示文稿系统拆解了协议层与帧层的层次关系,涵盖突发控制字组… · 2026/9/25 5:44:09

Atlas 300V 24G推理卡上部署YOLOv5:从ONNX到OM的完整实战指南
Atlas 300V 24G推理卡上部署YOLOv5:从ONNX到OM的完整实战指南

1. 先说结论:Atlas 300V 24G 到底是什么卡最近后台好几个朋友都在问同一个问题:Atlas 300V 24G 是运算加速卡吗?紧接着第二个问题就是,这卡能不能跑 YOLO?今天我把这俩问题一次性讲透,顺便把我在 Atlas 300… · 2026/9/25 5:44:09

2026年液压油缸推力大的品牌是哪个,国德液压源头实力厂商推荐
2026年液压油缸推力大的品牌是哪个,国德液压源头实力厂商推荐

2026年液压油缸推力大的品牌推荐——常州国德液压源头实力厂商,常州国德液压机械有限公司专注液压油缸、液压系统及成套设备研发制造,可提供定制化液压解决方案,以高可靠、长寿命的产品为工业装备输出稳定动力。品牌基础概况常州国德液压机械… · 2026/9/25 9:37:46

从snap.php到在线拍照:PHP文件上传与图像处理全链路实战
从snap.php到在线拍照:PHP文件上传与图像处理全链路实战

看到 http://www.cameroid.com/snap.php 这个地址,我第一反应是:老站长应该都记得这种"在线拍照"页面的标准长相——Flash 拉起摄像头,选个滤镜或相框,咔嚓一下,后端一个 PHP 文件接收照片,生成缩… · 2026/9/25 9:37:27

PHP对接EOS区块链:从RPC到签名推送的完整指南
PHP对接EOS区块链:从RPC到签名推送的完整指南

我第一次在搜索框里敲下php <<<eos的时候&#xff0c;搜索结果有点滑稽——左边是 PHP heredoc 语法讲解&#xff0c;右边是 EOS 区块链相关的帖子。这个组合并非巧合&#xff1a;<<<EOS在 PHP 里是合法的 heredoc 定界符&#xff0c;EOS 同时又是一条公链的… · 2026/9/25 9:37:27

Claude Code 快速上手,看这一篇就够了:TaoToken 统一 Key 接入与 settings.json 配置实战
Claude Code 快速上手,看这一篇就够了:TaoToken 统一 Key 接入与 settings.json 配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 9:37:27

ISG信息安全竞赛题型全解析:五大考点与备考路径
ISG信息安全竞赛题型全解析:五大考点与备考路径

简介&#xff1a;ISG信息安全竞赛题目类型文档&#xff0c;面向CTF初学者及备战ISG赛事的参赛者&#xff0c;系统梳理了比赛组织方式与题目体系。文档参照CTF竞赛模式&#xff0c;详解Web漏洞与渗透、软件逆向、漏洞挖掘利用、密码学原理及应用、杂项等五大类考点的具体能力要求… · 2026/9/25 9:37:21

Substrate底层框架解析:从区块链到材料生物,一次搞懂底层开发核心机制
Substrate底层框架解析:从区块链到材料生物,一次搞懂底层开发核心机制

1. 从“substrate”这个词说起&#xff1a;它到底是什么第一次看到“substrate”这个词&#xff0c;很多人会愣一下。它在不同圈子里指向完全不同的东西&#xff1a;做区块链的人第一反应是 Parity 那套区块链框架&#xff0c;做材料或化学的人想到的是“基底、衬底”&#xff… · 2026/9/25 9:37:21

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码