c3846da8ae
- 新增设计器静态依赖分析方案,阐述基于 AST 的代码片段解析与依赖图谱构建 - 新增实体生命周期引擎实现规范,定义引擎驱动的事件分发与交互触发策略 - 新增悬浮组件架构设计规范,明确底层数据统一与上层视图分离的核心原则 - 新增应用运行模式架构规范,严格区分设计态、预览态与运行态的边界 - 新增设计器选中与分组交互规范,定义选中态、激活态及下钻交互的行为矩阵
68 lines
5.5 KiB
Markdown
68 lines
5.5 KiB
Markdown
# DatAlive 实体生命周期引擎实现规范 (Entity Lifecycle Implementation)
|
||
|
||
## 1. 设计理念:引擎驱动生命周期 (Engine-Driven Lifecycle)
|
||
|
||
在基于 React 19+ 生态的低代码架构中,由于 Strict Mode、Concurrent Rendering 和 Suspense 的存在,React 组件的真实挂载/卸载行为往往不可预测(例如组件可能被多次挂载/卸载以检查副作用)。
|
||
|
||
因此,DatAlive 平台中的“业务生命周期”**严禁直接等价于 React 的生命周期(如 `useEffect`)**。我们必须采用**引擎驱动**模式:由底层的 `RuntimeEngine` 根据路由状态、全局数据流或用户行为,**显式地派发(Emit)**各个实体的生命周期事件。React 仅仅作为“被动接收状态并渲染”的视图层。
|
||
|
||
在底层 Schema 的定义中,无论是路由跳转、数据请求回调还是用户点击,这一切所谓的“生命周期钩子”,均被统一收口并泛化为 **`Interaction`(泛化事件侦听器)**。
|
||
|
||
---
|
||
|
||
## 2. 实体生命周期映射与 Interaction 触发策略
|
||
|
||
目前设计器中允许配置 `interactions: Interaction[]` 字段的实体,及其引擎侧的触发策略定义如下:
|
||
|
||
### 2.1 Application (应用根节点)
|
||
负责整个低代码应用启动和全局级别的状态拦截。
|
||
|
||
| Interaction.event (触发器) | 触发时机 | 引擎实现策略 |
|
||
| :--- | :--- | :--- |
|
||
| `onLaunch` | 应用配置加载完成,准备渲染根节点前 | 在 React `createRoot().render()` 执行前,由引擎主动解析执行。可用于初始化全局变量、鉴权校验等。 |
|
||
| `onError` | 全局未捕获的运行时异常(含数据流异常) | 绑定在 React ErrorBoundary 顶层,以及 Zustand / TanStack Query 的全局 Error Handler 中。 |
|
||
|
||
### 2.2 Route & Page (路由与页面容器)
|
||
视图层的状态闭环单元,处理路由切换带来的副作用(Route Guards)。
|
||
|
||
| Interaction.event (触发器) | 触发时机 | 引擎实现策略 |
|
||
| :--- | :--- | :--- |
|
||
| `onEnter` (Route级) | 路由准备进入该页面前 (Route Guards) | 挂载在路由监听层。可在此处派发 Action 发起鉴权,若鉴权失败可触发 Redirect Action 踢回登录页。 |
|
||
| `onLoad` (Page级) | 页面组件挂载,且前置预热数据已就绪 | 在页面容器初始化时触发。常用于重置当前页面的局部 Variables,或发起非预热的懒加载 Query。 |
|
||
| `onLeave` (Route级) | 路由准备离开该页面之前 | 路由切换前触发。用于清理定时器、WebSocket 或清空重型数据变量。 |
|
||
| `onResize` (Page级) | (大屏特有) 画布或窗口尺寸发生变化 | 引擎统一在 `window.addEventListener('resize')` 中做防抖处理,然后派发给当前激活的 Page。 |
|
||
|
||
### 2.3 Component (视图原子组件)
|
||
最核心的用户交互载体,其事件主要由 DOM 交互驱动,少部分由挂载周期驱动。
|
||
|
||
| Interaction.event (触发器) | 触发时机 | 引擎实现策略 |
|
||
| :--- | :--- | :--- |
|
||
| **交互类**: `onClick`, `onMouseEnter`, `onChange` 等 | 用户与组件进行真实物理交互时 | 通过标准 React Props 传递给具体的组件实现,例如 `<Button onClick={(e) => engine.dispatchInteraction('btn_1', 'onClick', e)} />`。 |
|
||
| **生命周期类**: `onMount`, `onUnmount` | 组件实例在画布中真实渲染/销毁时 | 不直接使用原生的 `useEffect`。需封装专门的 `useLowcodeMount` Hook,内部处理 React 18+ Strict Mode 的双次调用问题(幂等拦截),再向引擎上报。 |
|
||
|
||
### 2.4 Variable (响应式全局变量)
|
||
低代码状态驱动逻辑的核心连锁反应触发器。
|
||
|
||
| Interaction.event (触发器) | 触发时机 | 引擎实现策略 |
|
||
| :--- | :--- | :--- |
|
||
| `onChange` | 变量的值发生实质性突变时 | 在 Zustand Store 的 Reducer 层拦截,或通过 `store.subscribe` 监听。**必须进行深比较(Deep Equal)防止重复触发**。这是实现复杂表单联动(如省市级联清空)的核心机制。 |
|
||
|
||
### 2.5 Query / Mutation (CQRS 数据源请求)
|
||
异步控制流的核心,与后端交互的桥梁。
|
||
|
||
| Interaction.event (触发器) | 触发时机 | 引擎实现策略 |
|
||
| :--- | :--- | :--- |
|
||
| `onSuccess` | 数据请求成功并返回 2xx 状态码时 | 完美契合 TanStack Query。在其 `onSuccess` 回调中拦截并交由引擎执行配置的 Actions(如弹出成功 Toast,或触发其他 Query 的刷新)。 |
|
||
| `onError` | 请求失败、网络异常或业务报错时 | 在 TanStack Query 的 `onError` 回调中拦截。可在此处派发全局异常处理 Action。 |
|
||
| `onSettled` | 无论成功或失败,请求流程结束时 | 在 TanStack Query 的 `onSettled` 回调中拦截。用于统一下发如“关闭某个特定按钮的 Loading 态”之类的重置动作。 |
|
||
|
||
---
|
||
|
||
## 3. 架构优势总结
|
||
|
||
通过将以上所有的生命周期和事件收敛为 Schema 中的 `Interaction` 实体模型,我们获得了以下压倒性的架构优势:
|
||
|
||
1. **万法归宗 (Unified Control Flow)**:引擎只需要一个通用的“事件分发器(Event Dispatcher)”,就能处理从 DOM 鼠标点击到网络回调的所有异步行为。
|
||
2. **确定性 (Determinism)**:业务逻辑的执行不受 React 并发渲染机制的干扰。
|
||
3. **可测试性 (Testability)**:可以在 Node.js 环境下加载 Schema,通过调用 `engine.dispatchInteraction('query_1', 'onSuccess')` 直接测试复杂的联动数据流,完全无需真实的 DOM 参与。
|
||
4. **职责单一 (Separation of Concerns)**:React 只负责 `UI = f(state)`,`RuntimeEngine` 负责 `Event -> Action -> State Update` 的逻辑编排。 |