VTJ:核心概念

核心概念

引言

本篇"核心概念"旨在为VTJ低代码平台建立坚实的理论基础,围绕以下主题展开:低代码平台的基本原理、DSL(领域特定语言)的概念与作用、项目模型架构的设计思想;深入阐释ProjectModel、BlockModel、NodeModel三者的数据结构设计理念与相互关系;说明MVVM架构模式在平台中的落地方式、事件驱动机制与观察者模式的实现;介绍多端适配的原理、渲染器架构与代码生成机制。通过架构图与流程图,帮助开发者建立对平台工作原理与设计哲学的系统性认知。

项目结构

VTJ采用多包(monorepo)组织方式,核心能力分布在多个子包中:

  • 核心模型与协议:@vtj/core(ProjectModel、BlockModel、NodeModel及其Schema)
  • 设计器引擎:@vtj/designer(Engine、Designer、Simulator、Assets等)
  • 渲染器与Provider:@vtj/renderer(Provider、createRenderer、createLoader、路由与全局配置)
  • 解析器:@vtj/parser(模板与脚本解析,提取事件、指令、侦听器等)
  • 示例与测试:dev、docs等
graph TB subgraph "核心" CORE["@vtj/core<br/>模型与协议"] end subgraph "设计器" DESIGNER["@vtj/designer<br/>Engine/Designer/Simulator"] end subgraph "渲染" RENDERER["@vtj/renderer<br/>Provider/createRenderer"] end subgraph "解析" PARSER["@vtj/parser<br/>模板/脚本解析"] end subgraph "示例与文档" DEV["dev<br/>渲染器测试示例"] DOCS["docs<br/>Wiki与概念文档"] end CORE --> DESIGNER CORE --> RENDERER CORE --> PARSER DESIGNER --> RENDERER RENDERER --> DEV DOCS --> DESIGNER DOCS --> RENDERER

核心组件

本节聚焦平台的三大核心数据结构:ProjectModel(项目模型)、BlockModel(区块模型)、NodeModel(节点模型)。它们共同构成DSL的运行时载体,支撑设计器与渲染器的协作。

  • ProjectModel:统一管理项目元数据、页面与区块文件、依赖、API、元数据、国际化与环境变量等,提供CRUD与树形导航能力,并通过事件总线对外广播状态变更。
  • BlockModel:承载单个区块的DSL,包含状态、生命周期、方法、计算属性、侦听器、CSS、props/emit/slots/dataSources、节点树等,提供节点增删改移动与状态/函数/属性/事件/指令/数据源的管理。
  • NodeModel:描述单个组件或HTML标签的DSL节点,包含id/name/from、可见性/锁定、children/props/events/directives、slot等,提供父子关系维护与DSL序列化。
classDiagram class ProjectModel { +id : string +name : string +platform : PlatformType +pages : PageFile[] +blocks : BlockFile[] +currentFile : PageFile/BlockFile +dependencies : Dependencie[] +apis : ApiSchema[] +meta : MetaSchema[] +update(schema, silent) +active(file, silent) +deactivate(silent) +createPage(page, parentId, silent) +updatePage(page, silent) +movePageTo(id, parentId, silent) +createBlock(block, silent) +updateBlock(block, silent) +removeBlock(id, silent) +setApi(item, silent) +removeApi(name, silent) } class BlockModel { +id : string +name : string +state : BlockState +lifeCycles : Record<string, JSFunction> +methods : Record<string, JSFunction> +computed : Record<string, JSFunction> +watch : BlockWatch[] +css : string +props : Array<string|BlockProp> +emits : Array<string|BlockEmit> +slots : Array<string|BlockSlot> +dataSources : Record<string, DataSourceSchema> +nodes : NodeModel[] +locked : boolean +update(schema, silent) +toDsl(version) +addNode(node, target, position, silent) +removeNode(node, silent) +move(node, target, position, silent) +setState(name, value, silent) +setFunction(type, name, value, silent) +setWatch(watch, silent) +setProp(prop, silent) +setEmit(emit, silent) +setSlot(slot, silent) +setInject(inject, silent) +setDataSource(source, silent) } class NodeModel { +id : string +name : string +from : NodeFrom +invisible : boolean +locked : boolean +children : NodeModel[]|string|JSExpression +slot? : NodeSlot +props : Record<string, PropModel> +events : Record<string, EventModel> +directives : DirectiveModel[] +update(schema, silent) +setChildren(children, silent) +setSlot(slot, silent) +setProp(name, value, default, silent) +setEvent(event, silent) +setDirective(dir, silent) +appendChild(node, silent) +insertAfter(node, silent) +insertBefore(node, silent) +movePrev(silent) +moveNext(silent) +toDsl() } ProjectModel --> BlockModel : "管理页面/区块DSL" BlockModel --> NodeModel : "包含节点树"

架构总览

VTJ采用"模型-渲染-设计器"三层协同架构:

  • 模型层:以ProjectModel/BlockModel/NodeModel为核心,承载DSL与状态,提供事件广播。
  • 渲染层:Provider负责加载依赖、物料、路由与全局配置,createRenderer根据DSL生成可渲染组件。
  • 设计器层:Engine协调ProjectModel/BlockModel/NodeModel与Provider/Simulator/Assets,绑定事件流,实现所见即所得的编辑体验。
graph TB subgraph "模型层" PM["ProjectModel"] BM["BlockModel"] NM["NodeModel"] end subgraph "渲染层" PR["Provider"] CR["createRenderer"] CL["createLoader"] end subgraph "设计器层" ENG["Engine"] DES["Designer"] SIM["Simulator"] end PM --> ENG BM --> ENG NM --> ENG ENG --> PR PR --> CR CR --> CL ENG --> DES ENG --> SIM

详细组件分析

事件驱动与观察者模式

平台广泛采用事件总线(mitt封装)实现松耦合通信:

  • 模型变更事件:PROJECT_CHANGE、BLOCK_CHANGE、NODE_CHANGE、HISTORY_CHANGE等。
  • 设计器事件:文件激活/关闭、发布、出码、历史加载等。
  • 渲染器事件:按需触发渲染上下文更新。
sequenceDiagram participant UI as "设计器UI" participant ENG as "Engine" participant EM as "事件总线(emitter)" participant SRV as "Service" participant PR as "Provider" participant RND as "Renderer" UI->>ENG : 用户操作(新增/修改节点) ENG->>EM : 触发EVENT_NODE_CHANGE EM-->>ENG : 分发事件 ENG->>SRV : 保存文件DSL ENG->>PR : 更新Provider上下文 PR->>RND : 重建渲染器 RND-->>UI : 重新渲染

MVVM架构在平台中的应用

  • Model:ProjectModel/BlockModel/NodeModel承载数据与行为。
  • View:渲染器根据DSL生成Vue组件树,支持内置指令与自定义指令。
  • ViewModel:Engine与Provider协调模型与视图,Designer作为交互入口,Simulator提供预览与调试。
flowchart TD Start(["开始:用户在设计器中操作"]) --> Change["模型变更(节点/属性/事件/指令)"] Change --> Save["保存到服务端/本地缓存"] Save --> Reload["Provider加载DSL并创建渲染器"] Reload --> Render["渲染器生成组件树并挂载"] Render --> Preview["Simulator预览/调试"] Preview --> End(["结束:页面/区块生效"])

DSL(领域特定语言)的概念与作用

  • DSL是对页面/区块的结构化描述,包含节点树、状态、生命周期、方法、侦听器、指令、事件等。
  • 通过toDsl()/update()实现模型与DSL之间的双向转换,保证设计器与渲染器的一致性。
  • 解析器从模板/脚本中抽取事件、指令、侦听器等,反向完善DSL。
flowchart TD Dsl["DSL(JSON/JS对象)"] --> ToModel["toDsl() -> 模型"] ToModel --> Designer["设计器编辑"] Designer --> Update["update() -> 模型变更"] Update --> ToDsl["toDsl() -> 输出DSL"] ToDsl --> Parser["解析器抽取事件/指令/侦听器"] Parser --> Dsl

项目模型架构设计思想

  • 分层数据结构:ProjectModel聚合页面与区块,支持树形导航与页面/区块CRUD。
  • 事件驱动:通过统一事件总线广播项目级变更,确保设计器与渲染器同步。
  • 多端抽象:通过平台类型与全局配置,抽象不同端(web/h5/uniapp)差异。
flowchart TD Create["创建页面/区块"] --> UpdatePages["更新pages/blocks树"] UpdatePages --> Emit["广播EVENT_PROJECT_PAGES_CHANGE/EVENT_PROJECT_BLOCKS_CHANGE"] Emit --> Save["持久化到服务/本地"] Save --> Load["Provider加载DSL并初始化"] Load --> Render["渲染器渲染"]

多端适配原理与渲染器架构

  • Provider负责根据运行模式(设计/源码/预览)加载依赖、物料与路由。
  • 支持uniapp/web/h5等平台差异,通过全局配置、国际化、环境变量与路由策略适配。
  • createRenderer结合createLoader动态加载依赖DSL,实现按需渲染。
sequenceDiagram participant APP as "应用" participant PR as "Provider" participant SRV as "Service" participant RND as "Renderer" APP->>PR : 初始化(传入mode/adapter/router/globals) PR->>SRV : 加载项目DSL SRV-->>PR : 返回ProjectSchema PR->>PR : 解析依赖/物料/路由 PR->>RND : createRenderer(dsl, loader) RND-->>APP : 返回可挂载组件

代码生成机制

  • 出码触发:Engine监听PROJECT_GEN_SOURCE事件,调用service.genSource生成源码。
  • 生成范围:通常针对项目pages集合与当前ProjectModel DSL进行打包。
  • 结果落盘:生成物写入目标目录,供构建/发布流程使用。
sequenceDiagram participant UI as "设计器UI" participant ENG as "Engine" participant SRV as "Service" UI->>ENG : 触发出码(genSource) ENG->>SRV : genSource(projectDslWithPages) SRV-->>ENG : 返回生成结果 ENG-->>UI : 显示生成状态/产物

事件绑定与指令系统

  • 事件绑定:设计器通过事件绑定器选择事件名与处理函数,支持修饰符与校验。
  • 指令系统:支持v-if/v-show/v-for/v-html等内置指令,以及v-model派生(根据物料描述推导)。
  • 侦听器:支持JSFunction源与处理函数,支持深监听与立即执行。
flowchart TD Select["选择事件/指令"] --> Bind["绑定到NodeModel"] Bind --> Parse["解析器抽取事件/指令/侦听器"] Parse --> Update["更新DSL并触发模型变更"] Update --> Render["渲染器重新渲染"]

依赖分析

  • 模型层依赖:@vtj/core提供ProjectModel/BlockModel/NodeModel与协议定义。
  • 设计器层依赖:@vtj/designer依赖@vtj/core与@vtj/renderer,协调Engine/Designer/Simulator。
  • 渲染层依赖:@vtj/renderer依赖@vtj/core的协议与DSL,提供Provider与渲染器工厂。
  • 解析层依赖:@vtj/parser解析模板与脚本,产出事件/指令/侦听器等DSL片段。
graph LR CORE["@vtj/core"] --> DESIGNER["@vtj/designer"] CORE --> RENDERER["@vtj/renderer"] DESIGNER --> RENDERER PARSER["@vtj/parser"] --> CORE PARSER --> DESIGNER

性能考量

  • 事件风暴防护:通过事件静默更新(silent)减少不必要的广播与重渲染。
  • 懒加载与按需加载:Provider按运行模式加载依赖与物料,避免全量加载。
  • 缓存策略:Provider对URL DSL进行缓存,降低重复请求成本。
  • 渲染优化:通过上下文模式与组件懒加载,减少首屏压力。

故障排查指南

  • 事件未触发:确认事件名称与监听绑定是否一致,检查事件总线注册顺序。
  • DSL不一致:检查toDsl()/update()调用链,确保模型与DSL双向同步。
  • 渲染失败:核对Provider初始化参数(mode/adapter/router/globals),确认依赖与物料加载成功。
  • 指令/事件解析异常:检查解析器正则与表达式生成逻辑,确保事件名与处理函数匹配。

结论

VTJ通过清晰的模型层(ProjectModel/BlockModel/NodeModel)、完善的事件驱动与观察者模式、灵活的渲染器与Provider架构,以及强大的解析器与多端适配能力,构建了低代码平台的坚实理论基础与工程实践。理解这些核心概念与组件关系,有助于开发者高效地进行二次开发、扩展与集成。

附录

  • 项目模型与区块模型概念文档:项目模型和区块模型
  • 渲染器测试示例(DSL输入样例):渲染器测试视图
  • HTML到节点解析测试:HTML解析测试

参考资料

VTJ.PRO 是一个开源的、AI 驱动的 Vue 3 企业级应用开发平台。它通过 AI 智能体与可视化编排实现高效开发,并支持导出标准 Vue 代码以避免平台锁定。更多信息请访问:

相关推荐
楚国的小隐士6 小时前
在生产环境中和AI协作编程
ai·大模型·编程·软件工程·ai编程·软件架构
benbenAItalk7 小时前
数字人口播视频的批量生产实践:素材规范、任务编排与质量验收
java·前端·音视频
wangruofeng7 小时前
一个 Markdown 文件攒下 37k 星,i-have-adhd 给 AI 输出立了 10 条规矩
github·aigc·ai编程
2601_962885727 小时前
如何用 Python 扫描 A 股跳空缺口并统计缺口回补概率?
java·前端·python
西瓜太郎12348 小时前
Claude Code、Codex CLI、Gemini CLI 能否共用一枚 Key?先看协议选择矩阵
前端·api 网关·claude code·gemini cli·codex cli
全栈弄潮儿10 小时前
需求不清时,如何让 AI 帮你补全问题,而不是瞎写代码
aigc·openai·ai编程
一航jason10 小时前
Android平台推理框架及试用场景模型对比
android·人工智能·ai·架构·ai编程·llama
陈随易10 小时前
在Finch用了62亿词元,我认为这是新一代Agent工具之神
前端·人工智能·后端
一航jason10 小时前
Android 端侧大模型推理框架对比
android·人工智能·ai·ai编程·llama·ai-native
水域安全老周10 小时前
水趣钓鱼救生衣专利拆解:两级锁紧如何解决落水人衣分离
java·前端·网络