ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

NocoBase FlowEngine 深度解析:由流(Flow)驱动的前端无代码逻辑引擎(Model 与 Flow 架构与实践)

NocoBase FlowEngine 深度解析:由流(Flow)驱动的前端无代码逻辑引擎(Model 与 Flow 架构与实践) NocoBase FlowEngine 深度解析由流Flow驱动的前端无代码逻辑引擎Model 与 Flow 架构与实践【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase导读FlowEngine 是 NocoBase 2.0 全新推出的前端无代码/低代码开发引擎它的核心思想是把组件的属性与逻辑从静态定义变为由流Flow驱动模型Model负责承载组件状态与渲染流Flow负责将逻辑拆解为有序步骤Step并依次执行。本文以 FlowEngine 概述 为骨架结合 flow-engine 包源码 与同目录下的 快速开始 等文档完整讲解 Model、Flow、Step 三个核心概念及其底层实现并给出可直接复用的可编排按钮组件示例帮助你理解并上手 FlowEngine。FlowEngine 是什么FlowEngine 是 NocoBase 2.0 推出的前端无代码、低代码开发引擎。它将**模型Model与流Flow**结合达到两个目的简化前端逻辑将组件逻辑抽象为可复用的模型与流提升复用性与可维护性赋予配置与编排能力借助 Flow 的可配置能力让前端组件和业务逻辑具备无代码化的配置与编排能力。从源码结构看FlowEngine 的实现位于 packages/core/flow-engine/src入口文件 index.ts 统一导出了FlowEngine、FlowModel、FlowDefinition、FlowExecutor、各类 Registry、上下文Context与 React 渲染组件FlowModelRenderer等能力是一个完整的前端运行时引擎而非简单的状态管理库。为什么叫 FlowEngine名称由两部分组成含义直指其设计哲学Flow在 FlowEngine 中组件的属性和逻辑不再是静态定义的而是通过流来驱动和管理。流像数据流一样把逻辑拆解为有序的步骤Step逐步作用于组件Engine表达了这是一个驱动前端逻辑和交互的引擎而非单一组件库。所以FlowEngine 由流驱动的前端逻辑引擎。这一设计在源码中有直接体现FlowEngine 类 的核心职责就是管理流模型、动作、模型仓库它提供了注册模型类、创建/查找/持久化/替换/移动模型实例、注册流定义flow definitions与动作定义action definitions等一系列能力支撑起以流为驱动的运行时。什么是 Model—— 组件的逻辑大脑在 FlowEngine 里Model 是组件的抽象模型负责管理组件的属性Props和状态定义组件的渲染方式承载并执行Flow统一处理事件分发和生命周期。换句话说Model 是组件的逻辑大脑它让组件从静态定义变成可配置、可编排的动态单元。源码中的 FlowModelModel 的基类为FlowModel定义在 models/flowModel.tsx。从类结构可以看到它与逻辑大脑的对应关系实例属性uid唯一标识、props组件属性、stepParams步骤参数、parent/subModels父子模型关系、hidden、sortIndex等能力方法render()定义渲染方式、setProps()管理属性、dispatchEvent()事件分发、getFlow()/applyFlow()承载并执行 Flow、onInit()初始化生命周期等响应式基于formily/reactive的observable/observe实现状态可观测让 UI 能随模型状态自动更新。FlowModel同时支持通过registerFlow在类上注册全局 Flow对应源码中的GlobalFlowRegistry以及通过实例的flowRegistry注册实例级 Flow对应InstanceFlowRegistry这正是每个 UI 组件都可以通过 FlowModel 实例化并统一管理的实现基础。什么是 Flow—— 服务于 Model 的逻辑流在 FlowEngine 里Flow 是服务于 Model 的逻辑流。它的作用是将属性或事件逻辑拆解成步骤Step按流的方式依次执行可以管理属性变化PropsFlow也可以管理事件响应EventFlow让逻辑变得动态化、可配置化、可复用。源码中的 FlowDefinition 与三种定义Flow 的载体是FlowDefinition类见 FlowDefinition.ts它持有一组按sort排序的步骤FlowStep并提供addStep、getStep、moveStep、getSortedSteps等编排方法。Flow 定义的核心类型FlowDefinitionOptions定义在 types.ts关键字段如下字段类型说明keystringFlow 唯一标识源码注释建议采用xxxSettings风格如pageSettings、tableSettings、formSettings、buttonSettings、deleteSettings等便于识别维护titlestring人类可读的流标题建议与 key 保持一致风格如 Page settingsmanualboolean是否仅手动执行阻止自动执行没有on属性的 Flow 默认自动执行除非manual: truesortnumber执行顺序数值小的先执行默认 0可为负数onFlowEvent允许该 Flow 被dispatchEvent触发的事件配置用于声明触发事件名stepsRecordstring, StepDefinition步骤定义集合是 Flow 的主体defaultParamsRecordstring, any \| 函数Flow 级默认参数在模型实例化createModel时填充步骤参数的初始值仅填补缺失、不覆盖已有enableTitle/dividerboolean/top \| bottom设置面板中标题与分割线的显示控制Flow 相关的定义分三层均可在 types.ts 中找到EventDefinition事件定义用于事件注册表全局/模型类级本质上是ActionDefinition的类型别名types.ts#L278ActionDefinition动作定义types.ts#L157可复用的动作核心字段包括name唯一标识、handler(ctx, params)处理函数、uiSchema配置界面 schema、defaultParams、paramsRequired、scene适用场景如区块联动规则、按钮级联动规则、动态事件流等等StepDefinition步骤定义types.ts#L297扩展了ActionDefinition并增加步骤专属字段——key步骤在流内的唯一标识、use引用的已注册 ActionDefinition 名称、isAwait是否等待 handler默认 true、preset标记为true的步骤参数需要在创建时填写未标记的可在模型创建后再填写、uiMode配置界面的展示形态dialog/drawer/embed等。FlowExecutor见 executor/FlowExecutor.ts负责实际执行runFlow(model, flowKey, inputArgs, runId, eventName)会先通过model.getFlow(flowKey)获取 Flow创建FlowRuntimeContext注入reactView、inputArgs、runId等运行上下文再按排序后的步骤依次执行 handler并支持FlowExitException退出当前流与FlowExitAllException退出所有流等流程控制。如何理解这几个概念—— 水流比喻可以把Flow想象成一条水流Step 就像水流途径的节点每个 Step 承担一个小任务例如设置属性、触发事件、调用接口就像水流经过某个闸门或水车时会发生相应的作用流是有序的水流按照既定路径从上游到下游依次经过所有 StepFlow 里的逻辑也按照定义顺序执行。对应源码中FlowDefinition.getSortedSteps()按sort值排序、数值小的先执行流是可分叉和组合的一条水流可以分成多股小流也可以汇聚在一起Flow 同样可以拆分为多个子流或组合成更复杂的逻辑链路。源码中提供了 forkFlowModel.ts 与ForkFlowModel类型支持分叉执行subModels子模型机制则让一个模型可以组合出更复杂的结构流是可配置和可控制的水流的方向和流量可以通过水闸调整Flow 的执行方式和参数则通过配置stepParams来控制。比喻总结组件像一台水车需要有水流推动才能转动Model是水车的底座和控制器负责接收水流并驱动运作Flow就是那条水流按顺序经过每个 Step推动组件不断变化和响应。所以在 FlowEngine 中Flow 让逻辑像水流一样自然流动Model 则让组件成为水流的承载体和执行者。引擎层FlowEngine 如何承载这一切FlowEngineflowEngine.ts是整套体系的运行时中枢官方注释概括其核心能力注册、创建、查找、持久化、替换、移动模型支持流定义、动作定义、模型类继承与过滤集成 FlowEngineContext、FlowSettings 与 ReactView。注册能力Register方法作用源码位置registerModels({ MyModel })注册模型类key 为模型名value 为构造函数flowEngine.ts#L483registerModelLoaders({ DemoModel: { extends: BaseModel, loader: () import(...) } })注册异步模型加载器extends声明父类以支持异步子类发现flowEngine.ts#L503registerActions(actions)/registerEvents(events)注册全局动作与事件定义flowEngine.ts#L407setModelRepository(repository)设置模型仓库用于模型持久化与查询实现IFlowModelRepositoryfindOne/save/destroy/move/duplicateflowEngine.ts#L382创建能力CreatecreateModel(options)flowEngine.ts#L934是实例化的核心入口CreateModelOptionstypes.ts#L381支持uid、use模型类名或构造函数、props、flowRegistry、stepParams、subModels、parentId等选项。创建流程的关键环节解析模型类支持resolveUse动态解析链与异步 loader 兜底若 UID 已存在则直接返回既有实例幂等模型类不存在时降级为ErrorFlowModel并设置错误信息容错设计触发model:created生命周期事件通过引擎内置 Emitter 发射异步应用 Flow 级defaultParams仅填充缺失的 stepParams不阻塞创建递归创建subModels子模型。引擎还提供了createModelAsync先解析模型树再同步创建、resolveModelTree、getSubclassesOf/getSubclassesOfAsync模型类继承过滤与异步子类发现、moveModel/removeModel/saveModel等完整的模型管理 API。作用域与执行作用域引擎除了根FlowEngine还提供ViewScopedFlowEngine与BlockScopedFlowEngine通过 createViewScopedEngine / createBlockScopedEngine 创建实现视图/区块级别的引擎隔离与委托事件与调度ModelOperationSchedulerscheduler/ModelOperationScheduler.ts支持在模型生命周期节点beforeAllFlows/afterAllFlows/beforeFlow/afterFlow/beforeStep/afterStep见 types.ts#L241 的FlowEventPhase调度操作响应式与渲染ReactView集成 React 视图渲染FlowModelRenderercomponents/FlowModelRenderer.tsx负责将模型渲染为真实 UI并支持showFlowSettings开启配置界面。实战构建一个可编排的按钮组件下面把概念落到代码。完整的可运行示例见 flow-engine 目录下的快速开始 及其 demos 示例代码这里提炼核心三步。第一步用 FlowModel 渲染组件class MyModel extends FlowModel { render() { return Button {...this.props} /; } }const model await this.flowEngine.createModelAsync({ uid: my-model, use: MyModel, props: { type: primary, children: Primary Button, }, });FlowModelRenderer model{model} /第二步添加 PropsFlow让按钮属性可配置定义按钮属性的 FlowbuttonSettings通过uiSchema声明配置表单、handler将参数写回模型属性const buttonSettings defineFlow({ key: buttonSettings, title: 按钮设置, steps: { setProps: { title: 通用配置, uiSchema: { title: { type: string, title: 按钮标题, x-decorator: FormItem, x-component: Input }, type: { type: string, title: 类型, x-decorator: FormItem, x-component: Select, enum: [ { label: 主要, value: primary }, { label: 次要, value: default }, { label: 危险, value: danger }, { label: 虚线, value: dashed }, { label: 链接, value: link }, { label: 文本, value: text }, ], }, // icon 等字段同理…… }, defaultParams: { type: primary }, handler(ctx, params) { ctx.model.setProps(children, params.title); ctx.model.setProps(type, params.type); }, }, }, }); MyModel.registerFlow(buttonSettings);推荐用stepParams替代静态props可避免不可序列化数据如 React 组件的问题const model await this.flowEngine.createModelAsync({ uid: my-model, use: MyModel, stepParams: { buttonSettings: { setProps: { title: Primary Button, type: primary, }, }, }, });最后给渲染组件加上showFlowSettings即可启用属性配置界面FlowModelRenderer model{model} showFlowSettings /stepParams的结构与源码中的StepParams类型完全一致types.ts#L353外层以flowKey为键内层以stepKey为键最内层为具体参数对象{ [flowKey]: { [stepKey]: { [paramKey]: any } } }。第三步添加事件流EventFlow先在 PropsFlow 中无入侵地接入事件分发handler(ctx, params) { // ……设置其他属性 ctx.model.setProps(onClick, (event) { ctx.model.dispatchEvent(click, { event }); }); }再定义事件流让点击行为可配置const myEventFlow defineFlow({ key: clickSettings, on: click, // 声明由 dispatchEvent(click) 触发 title: 按钮事件, steps: { confirm: { title: 确认操作配置, uiSchema: { title: { type: string, title: 弹窗提示标题, x-decorator: FormItem, x-component: Input }, content: { type: string, title: 弹窗提示内容, x-decorator: FormItem, x-component: Input.TextArea }, }, defaultParams: { title: 确认操作, content: 你点击了按钮是否确认 }, async handler(ctx, params) { const confirmed await ctx.modal.confirm({ title: params.title, content: params.content }); await ctx.message.info(你点击了按钮确认结果${confirmed ? 确认 : 取消}); }, }, }, }); MyModel.registerFlow(myEventFlow);不同事件click、submit、close、openView、search、dropdownOpen等完整内置事件名见 types.ts#L218 的FlowEventName都可以注册对应的事件流满足复杂业务需求。执行时FlowExecutor.runFlow会先查找与flow.on匹配的事件定义将其作为eventStep注入步骤集合再依次执行FlowExecutor.ts#L101-L116。ReactComponent vs FlowModelFlow 并不会改变组件的实现方式它只是为 React 组件增加了对 PropsFlow 和 EventFlow 的支持让组件的属性和事件都可以通过可视化方式配置和编排ReactComponentButtonComponent → Propstitle/type/icon EventsonClick属性和事件静态硬编码FlowModelButtonModel → PropsFlow EventFlow属性和事件由步骤流驱动可配置、可编排、可复用。这种模式同样适用于表单、列表、图表等任何 UI 组件——在 FlowEngine 中一切皆可编排。总结FlowEngine 通过Model 承载、Flow 驱动的双层架构把前端组件的属性、状态、渲染、事件与生命周期统一抽象为可配置、可编排的单元Model 是组件的逻辑大脑FlowModel管理 Props/状态、定义渲染、执行 Flow、分发事件Flow 是服务于 Model 的逻辑流FlowDefinitionFlowExecutor把逻辑拆解为有序 Step支持 PropsFlow 与 EventFlow 两类用途FlowEngine 是运行时中枢负责模型注册/加载/创建/持久化、动作与事件注册、作用域隔离、调度与渲染集成。如果想继续深入可以按如下顺序阅读同目录文档快速开始动手示例、Flow 定义概览Event/Action/Step 三类定义、FlowModel 配置项、Flow 模型与 React 组件的对比 以及 学习路线图并对照源码 flowEngine.ts、flowModel.tsx、types.ts 逐一验证文中所述机制。【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表