数据结构定义
引言
本文件面向“数据结构定义”,聚焦于项目模型系统中的核心数据类型,包括 ProjectSchema、PageFile、BlockFile、ApiSchema 等关键接口的定义与用途。我们将逐项说明字段含义、数据类型、约束条件与默认值;阐述数据结构之间的关系与依赖;解释 ProjectSchema 如何整合页面、区块、数据源、国际化、环境变量等子模块;并给出数据验证规则、序列化/反序列化要点、与 DSL 的对应关系,以及最佳实践与设计原则。
项目结构
本项目采用多包工作区(monorepo)组织,核心数据协议位于 packages/core/src/protocols/schemas 下,模型层位于 packages/core/src/models 中,设计器侧的资产加载与物料解析位于 packages/designer/src/framework/assets.ts。文档 wiki 提供了项目与区块模型的高层说明。
graph TB
subgraph "协议层"
PS["ProjectSchema<br/>项目根模型"]
FS["File 协议<br/>FileType/BlockFile/PageFile"]
DS["DataSource 协议<br/>ApiSchema/MetaSchema"]
NS["Node 协议<br/>节点/事件/指令/插槽"]
BS["Block 协议<br/>区块DSL结构"]
HS["History 协议<br/>历史记录"]
SH["Shared 协议<br/>JSONValue/JSFunction/JSExpression"]
end
subgraph "模型层"
PM["ProjectModel<br/>项目模型"]
end
subgraph "设计器侧"
AS["Assets<br/>物料/分组/缓存"]
end
PS --> FS
PS --> DS
PS --> SH
FS --> BS
BS --> NS
BS --> DS
BS --> SH
HS --> BS
PM --> PS
AS --> BS
AS --> NS
核心组件
本节对关键数据结构进行逐一说明,并标注字段含义、类型、约束与默认值。
-
ProjectSchema(项目根模型)
- 字段与类型
- id?: string;唯一标识
- name: string;项目名称(必填)
- description?: string;项目简介
- platform?: PlatformType;平台,默认 web
- locked?: string;锁定标记
- homepage?: string;首页 pageId
- dependencies?: Dependencie[];项目依赖
- pages?: PageFile[];页面集合
- blocks?: BlockFile[];区块集合
- apis?: ApiSchema[];项目级 API 数据源
- meta?: MetaSchema[];配置化查询数据源
- config?: ProjectConfig;项目母版配置
- uniConfig?: UniConfig;UniApp 项目配置
- globals?: GlobalConfig;Web/H5 全局配置
- i18n?: I18nConfig;国际化配置
- env?: EnvConfig[];环境变量
- VTJ_PROJECT?: boolean;项目标记
- VERSION?: string;版本
- BASE_PATH?: string;部署目录
- UID?: string;全局项目标识
- 约束与默认
- name 必填;platform 默认 web;i18n.locale/fallbackLocale 默认 zh-CN;UID 自动生成
- 关系
- 整合 PageFile、BlockFile、ApiSchema、MetaSchema 等子模块
- 通过 ProjectModel.toDsl 输出 DSL 时会清理页面 DSL 的冗余字段
- 字段与类型
-
PageFile(页面文件)
- 字段与类型
- 继承自 BlockFile 的所有字段(见下一条)
- dir?: boolean;是否目录
- layout?: boolean;是否布局页面
- icon?: string;菜单图标
- children?: PageFile[];目录包含的页面
- mask?: boolean;是否在母版内
- hidden?: boolean;不在菜单显示
- raw?: boolean;源码文件(非低代码页面)
- pure?: boolean;纯净页面
- cache?: boolean;开启页面缓存
- meta?: Record<string, any>;路由元信息
- needLogin?: boolean;UniApp 专用,需登录才可访问
- style?: Record<string, any>;UniApp 页面窗口表现配置
- 约束与默认
- type 为 'page';fromType 一经确定不可更改;urls 在 fromType=UrlSchema 时仅允许一个 JSON 文件
- 关系
- 作为 ProjectSchema.pages 的元素;可嵌套形成目录树
- 字段与类型
-
BlockFile(区块文件)
- 字段与类型
- type: FileType;固定为 'block'
- id: string;唯一标识
- name: string;文件名
- title: string;显示标题
- category?: string;分组
- market?: MarketInstallInfo;从物料市场安装信息
- fromType?: 'Schema' | 'UrlSchema' | 'Plugin';创建来源(一经确定不可更改)
- preset?: boolean;是否预设(预设不可编辑/删除)
- urls?: string;资源 URL(fromType=Plugin 时允许多个,以逗号分隔)
- library?: string;Plugin 时的库名
- dsl?: BlockSchema;区块 DSL 内容
- 约束与默认
- fromType 默认 Schema;preset 默认 false;urls 在不同 fromType 下有不同约束
- 关系
- 作为 ProjectSchema.blocks 的元素;可被节点引用(NodeFrom)
- 字段与类型
-
ApiSchema(项目级 API 数据源)
- 字段与类型
- id: string;唯一标识
- name: string;接口名称
- label?: string;接口描述
- url: string;请求地址
- category?: string;分组
- method?: ApiMethod;请求方法,默认 get/post/put/delete/patch/jsonp
- settings?: Record<string, any>;请求设置
- headers?: JSExpression | JSFunction;请求头表达式/函数
- jsonpOptions?: Record<string, any>;jsonp 配置
- mockTemplate?: JSFunction;模拟数据模板
- mock?: boolean;是否启用模拟数据
- 约束与默认
- id/name/url 必填;method 默认 get
- 关系
- 作为 ProjectSchema.apis 的元素;可被页面级 DataSourceSchema 引用
- 字段与类型
-
MetaSchema(配置化查询数据源)
- 字段与类型
- id: string;唯一标识
- code: string;功能号
- title: string;报表名称
- queryCode: string;查询方案编号
- 约束与默认
- id/code/title/queryCode 必填
- 关系
- 作为 ProjectSchema.meta 的元素
- 字段与类型
-
NodeSchema(节点协议)
- 字段与类型
- id?: string;节点标识
- name: string;组件名
- from?: NodeFrom;来源(字符串/Schema/UrlSchema/Plugin)
- locked?: boolean;锁定
- invisible?: boolean;不可见
- props?: NodeProps;组件属性
- events?: NodeEvents;绑定事件
- directives?: NodeDirective[];内置指令
- children?: NodeChildren;子组件
- slot?: string | NodeSlot;插槽
- 约束与默认
- name 必填;from 可为字符串或对象;props/events/directives 等为可选
- 关系
- 作为 BlockSchema.nodes 的元素;与 BlockFile/BlockSchema 协同
- 字段与类型
-
BlockSchema(区块 DSL)
- 字段与类型
- id?: string;唯一标识
- name: string;组件名
- locked?: boolean;锁定
- inject?: BlockInject[];注入
- 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>;事件
- expose?: string[];暴露公共属性
- slots?: Array<string | BlockSlot>;插槽
- nodes?: NodeSchema[];节点树
- dataSources?: Record<string, DataSourceSchema>;数据源
- transform?: Record<string, string>;babel 转换缓存
- VTJ_BLOCK?: boolean;区块标记
- VERSION?: string;版本
- TEMPLATE_ID?: string;模板 id
- 约束与默认
- name 必填;nodes 为节点树;dataSources 为页面级引用数据源
- 关系
- 作为 BlockFile.dsl 使用;与 NodeSchema/DataSourceSchema 共同构成区块 DSL
- 字段与类型
-
HistorySchema(历史记录)
- 字段与类型
- id: string;页面或区块文件 id
- items?: HistoryItem[];历史记录项
- HistoryItem
- id: string;记录项唯一标识
- label: string;记录项描述
- dsl?: BlockSchema;记录项内容(区块 DSL)
- remark?: string;备注
- 关系
- 用于追踪页面/区块变更历史
- 字段与类型
-
Shared 类型(通用类型)
- JSONValue/JSONArray/JSONObject;JSExpression/JSFunction;DataType;PlatformType;ParseVueOptions 等
- 作用
- 为协议层提供统一的 JSON/JS 代码表示与平台类型定义
架构总览
ProjectSchema 作为项目根模型,聚合页面(PageFile)、区块(BlockFile)、数据源(ApiSchema/MetaSchema)、国际化(I18nConfig)、环境变量(EnvConfig)等子模块。BlockSchema 作为区块的 DSL 描述,内部包含节点树(NodeSchema)、数据源引用(DataSourceSchema)等。设计器侧通过 Assets 将物料(BlockSchema)与节点来源(NodeFrom)进行解析与缓存,最终渲染到页面。
classDiagram
class ProjectSchema {
+string name
+string? id
+PlatformType? platform
+PageFile[]? pages
+BlockFile[]? blocks
+ApiSchema[]? apis
+MetaSchema[]? meta
+ProjectConfig? config
+UniConfig? uniConfig
+GlobalConfig? globals
+I18nConfig? i18n
+EnvConfig[]? env
}
class PageFile {
+FileType type
+string id
+string name
+string title
+boolean? dir
+boolean? layout
+PageFile[]? children
+Record? meta
}
class BlockFile {
+FileType type
+string id
+string name
+string title
+string? urls
+string? library
+BlockSchema? dsl
}
class BlockSchema {
+string name
+NodeSchema[]? nodes
+Record~DataSourceSchema~? dataSources
}
class NodeSchema {
+string name
+NodeProps? props
+NodeEvents? events
+NodeDirective[]? directives
+NodeChildren? children
}
class ApiSchema {
+string id
+string name
+string url
+ApiMethod? method
}
class MetaSchema {
+string id
+string code
+string title
+string queryCode
}
ProjectSchema --> PageFile : "pages"
ProjectSchema --> BlockFile : "blocks"
ProjectSchema --> ApiSchema : "apis"
ProjectSchema --> MetaSchema : "meta"
BlockFile --> BlockSchema : "dsl"
BlockSchema --> NodeSchema : "nodes"
BlockSchema --> ApiSchema : "dataSources(ref)"
详细组件分析
ProjectSchema 与 ProjectModel
- 职责
- ProjectSchema 描述项目的完整结构与配置
- ProjectModel 负责项目实例化、更新、事件派发、DSL 导出等
- 关键行为
- update:批量更新项目属性并触发变更事件
- toDsl:导出 DSL 时清理页面/区块的 dsl 字段,避免冗余
- active:打开文件并派发激活事件
- 与 DSL 的关系
- ProjectModel.toDsl 返回的结构带有 VTJ_PROJECT 标记,作为项目 DSL 的根对象
sequenceDiagram
participant PM as "ProjectModel"
participant PS as "ProjectSchema"
participant EM as "事件发射器"
PM->>PM : update(schema, silent)
PM->>EM : 发射 EVENT_PROJECT_CHANGE
PM->>PM : toDsl(version?)
PM->>PM : 清理 pages/blocks 的 dsl
PM-->>PS : 返回带 __VTJ_PROJECT__ 的 DSL
PageFile 与 BlockFile
- PageFile
- 作为页面的文件描述,支持目录、布局、缓存、登录等特性
- 与 ProjectSchema.pages 集合关联
- BlockFile
- 作为可复用区块的文件描述,支持三种来源:Schema、UrlSchema、Plugin
- 与 ProjectSchema.blocks 集合关联
- fromType 与 urls 的约束
- fromType 一经确定不可更改
- UrlSchema 仅允许一个 JSON 文件;Plugin 支持多个文件(以逗号分隔)
flowchart TD
Start(["开始"]) --> CheckFrom["检查 fromType"]
CheckFrom --> |Schema| UseDSL["使用本地 BlockSchema"]
CheckFrom --> |UrlSchema| LoadURL["加载单个 JSON URL"]
CheckFrom --> |Plugin| LoadPlugin["加载多个 CSS/JS URL"]
UseDSL --> Done(["结束"])
LoadURL --> Done
LoadPlugin --> Done
BlockSchema 与 NodeSchema
- BlockSchema
- 描述区块的完整 DSL,包含状态、方法、计算属性、侦听器、样式、属性/事件/插槽、节点树、数据源等
- NodeSchema
- 描述节点的属性、事件、指令、插槽与子节点
- 关系
- BlockSchema.nodes 为 NodeSchema 数组;BlockSchema.dataSources 引用页面级数据源
classDiagram
class BlockSchema {
+NodeSchema[]? nodes
}
class NodeSchema {
+string name
+NodeProps? props
+NodeEvents? events
+NodeDirective[]? directives
+NodeChildren? children
}
BlockSchema --> NodeSchema : "nodes"
ApiSchema 与 MetaSchema
- ApiSchema
- 项目级 API 数据源,支持请求方法、请求头、jsonp、mock 等
- MetaSchema
- 配置化查询数据源,包含功能号、报表名、查询方案编号
- 关系
- 二者均作为 ProjectSchema 的子模块存在,供页面级 DataSourceSchema 引用
设计器侧资产加载(Assets)
- 职责
- 加载物料包、构建分组、解析 BlockSchema、缓存并生成物料描述
- 关键流程
- 根据 NodeFrom 解析来源:Schema/UrlSchema/Plugin
- 从服务获取 DSL 或插件物料,填充组件映射
- 自动根据 props 类型匹配设置器
sequenceDiagram
participant AS as "Assets"
participant SVC as "Service"
participant PRV as "Provider"
participant MAP as "componentMap"
AS->>AS : getBlockMaterial(from, blockName)
alt from.type == "Schema"
AS->>SVC : getFile(id, project)
SVC-->>AS : BlockSchema
else from.type == "UrlSchema"
AS->>PRV : getDslByUrl(url)
PRV-->>AS : BlockSchema
else from.type == "Plugin"
AS->>SVC : getPluginMaterial(from)
SVC-->>AS : MaterialDescription
AS->>MAP : set(name, material)
end
AS-->>MAP : 缓存并返回物料描述
依赖分析
- 协议层耦合
- ProjectSchema 依赖 File、DataSource、Shared 等协议
- BlockSchema 依赖 NodeSchema、DataSourceSchema、Shared
- PageFile/BlockFile 依赖 File 协议
- 模型层与协议层
- ProjectModel 以 ProjectSchema 为输入,提供更新、事件、DSL 导出能力
- 设计器侧
- Assets 通过 Service/Provider 获取 DSL,与 BlockSchema/NodeSchema 协同
graph LR
PS["ProjectSchema"] --> FS["File 协议"]
PS --> DS["DataSource 协议"]
PS --> SH["Shared 协议"]
FS --> BS["Block 协议"]
BS --> NS["Node 协议"]
BS --> DS
PM["ProjectModel"] --> PS
AS["Assets"] --> BS
AS --> NS
性能考虑
- DSL 导出优化
- ProjectModel.toDsl 会清理 pages/blocks 的 dsl 字段,避免序列化冗余
- cleanPagesDsl 递归清理子页面 dsl,降低体积
- 设计器缓存
- Assets 使用 caches 缓存已解析的 DSL,减少重复请求
- 数据结构扁平化
- PageFile.children 采用数组嵌套,便于遍历与渲染;建议控制层级深度
故障排查指南
- fromType 与 urls 不一致
- 症状:fromType=UrlSchema 但 urls 包含多个值,或 fromType=Plugin 但 urls 格式错误
- 处理:确保 UrlSchema 仅一个 JSON 文件;Plugin 多文件以逗号分隔
- 页面/区块 DSL 过大
- 症状:序列化体积过大
- 处理:调用 cleanPagesDsl 清理 dsl;在导出前执行 ProjectModel.toDsl
- 物料解析失败
- 症状:getBlockMaterial 返回空
- 处理:确认 NodeFrom 类型与参数;检查服务端/URL 是否可达;查看缓存是否命中
结论
本文系统梳理了项目模型中的核心数据结构:ProjectSchema、PageFile、BlockFile、ApiSchema、MetaSchema、BlockSchema、NodeSchema、HistorySchema 以及 Shared 类型。明确了字段语义、类型、约束与默认值,阐述了它们之间的关系与依赖,并结合 ProjectModel 的 DSL 导出与 Assets 的物料解析流程,给出了序列化/反序列化的注意事项与最佳实践。遵循本文的设计原则与约束,可确保项目模型在设计器与渲染器之间稳定流转。
附录
- 与 DSL 的对应关系
- ProjectModel.toDsl 输出的 ProjectSchema 带有 VTJ_PROJECT 标记,作为项目 DSL 根对象
- BlockFile.dsl 为 BlockSchema,作为区块 DSL
- NodeSchema 作为 BlockSchema.nodes 的元素,承载节点属性、事件、指令与子节点
- 参考文档
- 项目与区块模型的高层说明可参考 wiki 文档
参考资料
VTJ.PRO 是一个开源的、AI 驱动的 Vue 3 企业级应用开发平台。它通过 AI 智能体与可视化编排实现高效开发,并支持导出标准 Vue 代码以避免平台锁定。更多信息请访问:
- 📘 官方文档:vtj.pro/
- 🌐 在线平台:app.vtj.pro/
- 📦 开源仓库:gitee.com/newgateway/…