低代码编排引擎怎么讲
一句话先定性
编排引擎不是“拖拽功能”,而是把编辑行为稳定地翻译成对页面 schema 的修改。
30 秒版本
如果让我讲低代码编排引擎,我会先说它的本质不是拖拽,而是“编辑动作如何落到数据模型上”。也就是说,用户拖一个组件、移动一个节点、改一个容器布局,这些最终都要转成对 schema 的插入、移动、删除和更新。真正的难点在于插入位置计算、拖拽反馈、性能优化,以及怎么让编辑态逻辑不污染运行态。
1 分钟版本
我会把低代码编排引擎理解成一个“编辑动作转数据修改”的系统。用户在画布上做的拖拽、插入、移动,看上去是 UI 交互,但本质上都要被转换成对 schema 的操作。
所以我一般先从数据结构讲起,比如页面拆成组件树和属性表,结构和属性解耦。这样插入和移动只改树,改属性只改字典,后面做撤销重做、版本管理和性能优化都会更清楚。
然后再讲交互层。拖拽开始时先收集可放置区域,拖拽过程中做碰撞检测,判断应该插到目标节点的上、下、左、右,再把这个结果转成最终的插入 payload。这里视觉反馈和性能都很关键,因为用户看到的是一条蓝线、一个插入提示,但背后其实是在做投放区域计算和命中判断。
2 到 3 分钟版本
编排引擎这个题,我一般不会说“我做了拖拽功能”,因为那样会显得太轻。
我会先说,低代码编排引擎本质上是在解决一个转换问题:怎么把用户在编辑器里的动作,稳定地映射成对页面 schema 的修改。因为编辑器里真正有价值的,不是 DOM 位置变了,而是页面模型变了。
所以第一件事是数据结构要清楚。我的倾向是把页面拆成组件树和属性表两部分,类似 tree + blocks。这样层级关系和属性数据解耦之后,插入、移动、删除、更新的边界会比较明确,也更适合后面做撤销重做、diff 和最小更新。
第二件事是拖拽链路。拖拽开始时我会先生成或收集可投放区域,拖拽过程中根据鼠标位置或指针位置去做碰撞检测,判断当前应该命中哪个容器、插在谁前面或后面,然后把这个位置通过 indicator 或蓝线反馈给用户。等拖拽结束后,再把结果转成统一的插入 payload,比如
parentId、relativeId、position,最后交给 store 去修改 schema。第三件事是性能。小页面时,很多实现都能工作,但一旦页面上有几百上千个节点,如果你每次
dragmove都去遍历 DOM、算布局,页面会很快卡掉。所以我更倾向于在拖拽开始时预计算可投放区域,把高频拖动阶段尽量变成轻量 JS 计算,而不是反复读写 DOM。第四件事是编辑态和运行态分离。编排引擎只服务编辑态,负责高亮、选中、拖拽、指示器和插入逻辑;运行态只负责真正渲染业务页面。两者如果不分,后面会越来越难维护。
所以如果让我总结,编排引擎真正要讲清楚的,是数据结构、拖拽链路、性能策略和编辑态边界,而不只是“我支持组件拖拽”。
如果面试官追问“为什么不用原生 drag 事件”
我一般会从控制力和兼容性讲。原生 drag 事件虽然简单,但黑盒程度比较高,很多细节反馈不够可控;而低代码编辑器通常需要更细粒度的拖拽反馈、碰撞检测和插入指示,所以我更倾向于用 pointer / mouse 体系或者类似
interact.js这种更可控的方案。
如果面试官追问“怎么做精确插入”
我会说关键不是 drop 时刻,而是 dragmove 过程。因为精确插入本质上要在拖拽过程中持续判断当前命中的区域,再把这个命中结果可视化给用户。最后 drop 只是消费已经算好的结果。
最后一句收尾
所以我不会把编排引擎讲成拖拽组件,而会讲成一套把编辑动作映射成 schema 变更的核心机制。