VTJ:项目模型架构

0 阅读6分钟

引言

本文件面向VTJ平台的“项目模型架构”,系统性阐述ProjectModel、BlockModel、NodeModel三类核心数据模型的设计理念、实现细节与协作关系。文档聚焦以下目标:

  • 解释项目模型的层次结构、数据继承关系与职责划分
  • 说明ProjectModel如何管理项目配置、页面列表与全局设置
  • 介绍BlockModel的区块定义、复用机制与版本管理
  • 阐述NodeModel的节点抽象、属性系统与事件绑定
  • 提供模型间协作关系图、数据流转过程与状态管理模式
  • 给出具体代码示例路径、数据结构定义与使用场景

项目结构

VTJ的核心模型位于packages/core模块中,采用“协议定义 + 模型实现 + 类型声明”的分层组织方式:

  • 协议层:定义跨层共享的数据契约(如ProjectSchema、BlockSchema、NodeSchema)
  • 模型层:提供可序列化的领域模型(ProjectModel、BlockModel、NodeModel)
  • 类型层:导出TS类型声明,便于上层消费与IDE提示
graph TB
subgraph "协议层"
PJS["ProjectSchema<br/>项目协议"]
BJS["BlockSchema<br/>区块协议"]
NJS["NodeSchema<br/>节点协议"]
end
subgraph "模型层"
PM["ProjectModel<br/>项目模型"]
BM["BlockModel<br/>区块模型"]
NM["NodeModel<br/>节点模型"]
end
subgraph "类型层"
PDT["project.d.ts"]
BDT["block.d.ts"]
NDT["node.d.ts"]
end
PJS --> PM
BJS --> BM
NJS --> NM
PM --> PDT
BM --> BDT
NM --> NDT

核心组件

本节概览三大模型的职责边界与关键能力。

  • ProjectModel(项目模型)

    • 职责:统一管理项目级配置、页面树、区块库、API与元数据;提供文件生命周期操作(创建/更新/移动/复制/删除)、依赖管理、国际化与环境变量配置、发布与出码等
    • 关键点:以事件总线驱动变更通知;提供toDsl序列化能力;维护当前激活文件currentFile
  • BlockModel(区块模型)

    • 职责:封装可复用组件的定义与行为,包括状态、方法、计算属性、生命周期、侦听器、CSS、属性、事件、插槽、数据源、节点树等
    • 关键点:节点树管理(增删改移、克隆、层级锁定/解锁);toDsl序列化并带版本号;事件广播
  • NodeModel(节点模型)

    • 职责:抽象单个UI节点(组件或HTML标签),承载属性、事件、指令、插槽与子节点树
    • 关键点:父子关系与兄弟顺序维护;属性/事件/指令的增删改查;可见性与锁定传播;toDsl序列化

架构总览

三大模型形成“项目-区块-节点”的树形分层结构,ProjectModel持有页面与区块文件列表,每个文件内部嵌套BlockModel,BlockModel内部维护NodeModel树。

7376788d-95de-48cf-bc30-67aa35c6e47b.png

详细组件分析

ProjectModel 分析

  • 设计要点
    • 以静态属性列表控制可更新字段,确保update的可控性与一致性
    • 通过事件常量与事件总线对外广播变更,便于上层订阅与响应
    • 页面树支持目录与布局混合结构,提供递归遍历、查找父节点、移动与复制等能力
    • 区块与页面互转:将页面保存为区块,或将区块作为页面DSL使用
    • 配置管理:项目配置、UniApp配置、全局配置、国际化与环境变量均提供原子setter
  • 数据结构与复杂度
    • 页面查找:递归遍历 pages,最坏O(N)
    • 页面移动:先定位父节点O(N),再splice,整体O(N)
    • 依赖/API/Meta去重:基于名称或ID匹配,平均O(M)
  • 使用场景
    • 新建页面并自动激活
    • 将页面保存为区块复用
    • 更新项目配置或国际化设置
    • 发布与出码流程触发
sequenceDiagram
participant UI as "设计器/UI"
participant PM as "ProjectModel"
participant EM as "事件总线"
participant BM as "BlockModel"
UI->>PM : "创建页面"
PM->>PM : "生成ID/默认DSL"
PM->>EM : "广播页面变更事件"
PM-->>UI : "返回页面对象"
UI->>PM : "保存为区块"
PM->>BM : "基于页面DSL创建BlockModel"
PM->>PM : "写入blocks列表"
PM->>EM : "广播区块变更事件"
PM-->>UI : "完成"

BlockModel 分析

  • 设计要点
    • 以normalAttrs集中管理可序列化字段,toDsl输出包含版本号
    • 节点树管理:支持在指定位置插入、移动、克隆与删除;支持层级锁定/解锁传播
    • 行为与元数据:方法、计算属性、生命周期、侦听器、CSS、属性、事件、插槽、注入、数据源等
  • 数据结构与复杂度
    • 节点插入/删除/移动:基于数组索引操作,O(K)(K为兄弟节点数)
    • 节点克隆:深度克隆DSL后重建NodeModel,O(D)(D为节点深度)
    • isChild判断:递归遍历子树,最坏O(N)
  • 使用场景
    • 在区块内新增/调整组件布局
    • 定义组件属性、事件与插槽
    • 管理组件状态与侦听器
flowchart TD
Start(["开始"]) --> AddNode["添加节点到目标位置"]
AddNode --> HasTarget{"是否有目标节点?"}
HasTarget --> |否| Append["追加到根节点末尾"]
HasTarget --> |是| Pos{"位置类型"}
Pos --> |left/top| InsertBefore["插入到目标前"]
Pos --> |right/bottom| InsertAfter["插入到目标后"]
Pos --> |inner| AppendChild["作为目标子节点"]
InsertBefore --> Done(["结束"])
InsertAfter --> Done
AppendChild --> Done
Append --> Done

NodeModel 分析

  • 设计要点
    • 节点唯一标识与来源标记;父子关系与兄弟顺序维护
    • 属性、事件、指令采用专用模型封装,支持增删改查与序列化
    • 可见性与锁定支持向下传播,保证批量操作一致性
  • 数据结构与复杂度
    • 子节点增删改:数组索引操作,O(S)(S为兄弟节点数)
    • 节点移动:在父节点兄弟数组中重排,O(S)
    • 销毁:递归销毁子树并解除父子关系,O(N)
  • 使用场景
    • 在设计器中拖拽/排序组件
    • 动态绑定事件与指令
    • 批量锁定/解锁与显隐控制
sequenceDiagram
participant UI as "设计器/UI"
participant NM as "NodeModel"
participant Parent as "父节点"
participant EM as "事件总线"
UI->>NM : "插入到某节点之后"
NM->>Parent : "请求在父节点中插入"
Parent->>Parent : "兄弟数组splice"
Parent->>EM : "广播节点变更事件"
Parent-->>UI : "完成"

依赖分析

  • 模型间耦合
    • ProjectModel持有BlockModel实例(通过文件DSL),但不直接持有NodeModel
    • BlockModel直接持有NodeModel数组,形成树状组合关系
    • NodeModel通过父指针向上回溯,形成双向关联
  • 事件与工具
    • 三大模型均通过事件总线对外广播变更,便于解耦
    • 工具入口导出事件总线与通用工具,供模型层使用
graph LR
EM["事件总线"] --> PM["ProjectModel"]
EM --> BM["BlockModel"]
EM --> NM["NodeModel"]
PM --> BM
BM --> NM

性能考虑

  • 序列化与版本
    • toDsl输出包含版本号,便于增量比较与缓存失效
    • 页面树清理:在导出前清理DSL中的冗余字段,降低体积
  • 树操作
    • 节点移动与插入基于数组索引,建议在批量操作时合并为单次事件广播
    • 锁定/可见性传播为递归操作,避免在超大树上频繁触发
  • 事件风暴
    • 大规模节点变更时,优先使用静默模式(silent)减少事件风暴
  • 查询优化
    • 页面查找与去重逻辑基于线性扫描,建议在高频场景引入索引结构(如按名称/ID的Map)

故障排查指南

  • 常见问题
    • 页面/区块未找到:检查ID或名称是否重复,确认existXxxName与exclude列表
    • 节点移动异常:确认目标节点存在且允许插入(目录/布局节点需特殊处理)
    • 事件未触发:确认silent参数与事件常量是否正确传递
  • 排查步骤
    • 使用toDsl导出最小化DSL,定位问题节点
    • 逐步撤销最近变更,确认问题触发点
    • 检查事件总线订阅者是否遗漏或重复注册

结论

VTJ的项目模型架构以清晰的分层与强约束的协议为基础,通过ProjectModel、BlockModel、NodeModel三者协同,实现了从项目配置到页面/区块再到组件级别的全链路建模。其事件驱动与序列化能力为设计器、渲染器与生成器提供了稳定的数据通道。建议在实际工程中:

  • 严格遵循协议字段,避免越界更新
  • 在批量操作时合理使用静默模式与事件合并
  • 对超大页面树进行必要的索引与懒加载策略

参考资料

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