AI 驱动的 Vue3 应用开发平台 深入探究(二十四):API与参考之Provider API 参考

Provider API 参考

Provider API 是 VTJ 中数据持久化、代码生成和跨平台操作的基础抽象层。这份详尽的参考文档介绍了 Service 抽象类、其协议接口、Schema 定义以及使用自定义后端扩展 Provider 系统的实现模式。

架构概览

Provider API 架构遵循 协议优先设计,所有数据操作都通过标准化的 Service 接口进行。这种抽象实现了可插拔的存储后端(本地文件、云服务、数据库),同时在整个 VTJ 生态系统中保持一致的 API 契约。

flowchart TB subgraph Application["VTJ Applications"] Designer["Designer IDE"] Runtime["Renderer Runtime"] end subgraph CoreProtocol["@vtj/core - Protocols"] Service["Service Abstract Class"] Schemas["Schema Definitions"] Assets["Material Assets"] end subgraph Implementations["Provider Implementations"] Local["Local File System"] Cloud["Cloud Service"] Custom["Custom Provider"] end subgraph Repositories["Data Access Layer"] JsonRepo["JSON Repository"] VueRepo["Vue Repository"] PluginRepo["Plugin Repository"] StaticRepo["Static Repository"] end Designer -->|API Calls| Service Runtime -->|API Calls| Service Service -->|Abstract Methods| Local Service -->|Extends| Cloud Service -->|Extends| Custom Local --> JsonRepo Local --> VueRepo Local --> PluginRepo Local --> StaticRepo Service -->|Uses Types| Schemas Service -->|Uses Types| Assets

Service 抽象类

Service 抽象类定义了 Provider 实现的完整契约,位于 packages/core/src/protocols/service.ts。所有方法均返回 Promises 以支持跨不同存储后端的异步操作。

项目管理 API

方法 目的 参数 返回类型
getExtension() 获取设计器扩展配置 - `Promise<VTJConfig
init() 使用 Schema 初始化项目 project: Partial<ProjectSchema>, isInit?: boolean Promise<ProjectSchema>
saveProject() 持久化项目 Schema project: ProjectSchema, type?: string Promise<boolean>
saveMaterials() 保存物料描述 project: ProjectSchema, materials: Map<string, MaterialDescription> Promise<boolean>
publish() 完整项目代码生成 project: ProjectSchema Promise<boolean>

getExtension 方法检索包括路由模式、基础路径、平台设置和身份验证选项在内的 VTJ 运行时配置,定义见 VTJConfig 接口。init 方法通过 isInit 标志支持新项目创建和现有项目加载。

文件管理 API

方法 目的 参数 返回类型
saveFile() 持久化页面或区块文件 file: BlockSchema, project?: ProjectSchema Promise<boolean>
getFile() 获取文件 Schema id: string, project?: ProjectSchema Promise<BlockSchema>
removeFile() 从项目中删除文件 id: string, project?: ProjectSchema Promise<boolean>
publishFile() 为单个文件生成代码 `project: ProjectSchema, file: PageFile BlockFile`

文件操作使用 BlockSchema,它定义了完整的 DSL 结构,包括组件树 (nodes)、状态管理 (state, computed, watch)、生命周期钩子 (lifeCycles)、方法、样式和数据源。文件通过 PageFileBlockFile 接口分类为 PageFileBlockFile

历史记录管理 API

方法 目的 参数 返回类型
saveHistory() 持久化文件历史记录 history: HistorySchema, project?: ProjectSchema Promise<boolean>
getHistory() 获取文件历史记录 id: string, project?: ProjectSchema Promise<HistorySchema>
removeHistory() 删除文件历史记录 id: string, project?: ProjectSchema Promise<boolean>
saveHistoryItem() 添加历史版本 fId: string, item: HistoryItem, project?: ProjectSchema Promise<boolean>
getHistoryItem() 获取特定版本 fId: string, id: string, project?: ProjectSchema Promise<HistoryItem>
removeHistoryItem() 删除历史版本 fId: string, ids: string[], project?: ProjectSchema Promise<boolean>

历史记录跟踪基于 HistorySchema,它将文件 ID 与 HistoryItem 记录数组关联,每条记录包含 DSL 快照、时间戳(隐式在 Schema 结构中)、标签和可选备注。

代码生成 API

方法 目的 参数 返回类型
genVueContent() 将 DSL 转换为 Vue 源代码 project: ProjectSchema, dsl: BlockSchema Promise<string>
parseVue() 解析 Vue 源代码为 DSL project: ProjectSchema, options: ParseVueOptions Promise<BlockSchema>
genSource() 生成完整项目归档 project: ProjectSchema Promise<string>
createRawPage() 创建源码模式页面 file: PageFile, project?: ProjectSchema Promise<boolean>
removeRawPage() 删除源码模式页面 id: string, project?: ProjectSchema Promise<boolean>

genVueContent 方法执行 DSL 到代码的转换,如 DSL 转 Vue 代码生成 中所述。parseVue 方法接受 ParseVueOptions,其中包含文件 ID、名称和源代码内容,实现了 Vue 源代码转 DSL 解析 中描述的双向转换。

静态文件管理 API

方法 目的 参数 返回类型
uploadStaticFile() 上传资源到项目 file: File, projectId: string `Promise<StaticFileInfo
getStaticFiles() 列出项目静态文件 projectId: string Promise<StaticFileInfo[]>
removeStaticFile() 删除静态资源 name: string, projectId: string, file?: StaticFileInfo Promise<boolean>
clearStaticFiles() 删除所有静态文件 projectId: string Promise<boolean>

静态文件使用 StaticFileInfo 进行跟踪,其中包含可选的 ID、文件名和必需的文件路径属性。这些方法支持图片、样式表和其他资源的项目级资源管理。

插件物料 API

方法 目的 参数 返回类型
getPluginMaterial() 获取插件组件描述 from: NodeFromPlugin `Promise<MaterialDescription

此方法支持从插件源动态加载物料,支持 NodeFromPlugin 接口,该接口定义了包含 URL 数组和可选库导出名称的插件类型。

核心 Schema 定义

Project Schema

ProjectSchema 接口代表完整的项目配置:

typescript 复制代码
interface ProjectSchema {
  id?: string;
  name: string;
  description?: string;
  platform?: PlatformType;
  pages?: PageFile[];
  blocks?: BlockFile[];
  homepage?: string;
  dependencies?: Dependencie[];
  apis?: ApiSchema[];
  meta?: MetaSchema[];
  config?: ProjectConfig;
  uniConfig?: UniConfig;
  globals?: GlobalConfig;
  i18n?: I18nConfig;
  env?: EnvConfig[];
  __VTJ_PROJECT__?: boolean;
  __VERSION__?: string;
  __BASE_PATH__?: string;
  __UID__?: string;
}

关键配置部分:

  • pagesPageFile 对象数组,定义页面路由、布局和元数据
  • blocksBlockFile 对象数组,用于可复用组件定义
  • dependenciesDependencie 数组,指定带有平台目标的 npm 包
  • globalsGlobalConfig,用于全局样式、Store、访问控制和 HTTP 拦截器
  • i18nI18nConfig,用于包含区域设置和消息定义的国际化

Block Schema

BlockSchema 代表核心 DSL 结构:

typescript 复制代码
interface BlockSchema {
  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>;
}

核心组件:

  • nodesNodeSchema 数组,定义组件树结构
  • stateBlockState 映射响应式数据值
  • methods :将方法名称映射到 JSFunction 实现的映射
  • computed :将计算属性名称映射到 JSFunction 表达式的映射
  • watchBlockWatch 数组,用于响应式数据观察
  • lifeCycles :生命周期钩子(onMounted、onBeforeUnmount 等),映射到 JSFunction
  • dataSources :用于 API 调用和数据转换的 DataSourceSchema 映射

💡 transform 属性缓存 Babel 转译后的代码,用于运行时优化,避免在渲染周期中重复编译方法和计算函数字符串。

Node Schema

NodeSchema 定义 DSL 树中的单个组件节点:

typescript 复制代码
interface NodeSchema {
  id?: string;
  name: string;
  from?: NodeFrom;
  locked?: boolean;
  invisible?: boolean;
  props?: NodeProps;
  events?: NodeEvents;
  directives?: NodeDirective[];
  children?: NodeChildren;
  slot?: string | NodeSlot;
}

关键属性:

  • name:组件名称(例如 "el-button"、"a-input")
  • fromNodeFrom,指定来源类型(包名、Schema 引用、URL 或插件)
  • propsNodeProps,包含组件属性,包括 keyrefstyleclass 等特殊键
  • eventsNodeEvents,将事件名称映射到 NodeEvent 处理程序
  • directivesNodeDirective 数组,用于 v-if、v-for、v-model 等
  • children:嵌套节点数组或表达式
  • slot:插槽放置定位,带有可选的作用域参数

Data Source Schema

DataSourceSchema 支持声明式数据获取:

typescript 复制代码
interface DataSourceSchema {
  type: DataSourceType;
  ref?: string;
  name: string;
  label?: string;
  transform?: JSFunction;
  test?: JSFunction;
  mockTemplate?: JSFunction;
}

数据源类型:

  • api :引用项目级 ApiSchema,包含方法、URL、Headers 和 Mock 设置
  • cube:配置的查询集成(特定于后端)
  • meta:配置的元数据查询集成
  • mock :使用 mockTemplate 的纯 Mock 数据

transform 属性允许数据处理函数将原始 API 响应转换为 UI 就绪格式,而 test 提供开发时的测试功能。

Material Schema

物料描述通过 MaterialDescription 接口定义可用组件:

typescript 复制代码
interface MaterialDescription {
  name: string;
  alias?: string;
  parent?: string;
  icon?: string;
  label?: string;
  doc?: string;
  categoryId?: number | string;
  props?: MaterialProp[];
  events?: Array<string | MaterialEvent>;
  slots?: Array<string | MaterialSlot>;
  snippet?: Partial<NodeSchema>;
  parentIncludes?: boolean | string[];
  childIncludes?: boolean | string[];
  hidden?: boolean;
  from?: NodeFrom;
  id?: string;
  package?: string;
}

组件注册:

  • name:设计器引用的唯一组件标识符
  • alias:原始库导出名称(例如 ant-design-vue 中的 "Button")
  • parent:子组件的父组件(例如 "Button.Group" 的 "Button")
  • snippet:组件拖拽到画布时的初始 DSL 结构
  • parentIncludes:限制放置到特定的父组件中
  • childIncludes:限制允许的子组件类型

属性通过 MaterialProp 定义,包含类型规范、默认值和设计器属性面板的 Setter 配置。

共享协议类型

表达式类型

VTJ 通过专用接口区分静态值和运行时可执行代码:

typescript 复制代码
interface JSExpression {
  type: "JSExpression";
  id?: string;
  value: string;
}

interface JSFunction {
  type: "JSFunction";
  id?: string;
  value: string;
}

这些接口使 DSL 结构能够区分字面量值和需要运行时求值的代码,支持 DSL Schema 和数据模型 中描述的声明式数据绑定模式。

VTJ Configuration

VTJConfig 接口配置运行时行为:

typescript 复制代码
interface VTJConfig {
  enhance?: boolean | EnhanceConfig;
  extension?: ExtensionConfig;
  history?: "hash" | "web";
  base?: string;
  pageRouteName?: string;
  pageBasePath?: string;
  __BASE_PATH__?: string;
  remote?: string;
  auth?: string | (() => Promise<any>);
  checkVersion?: boolean;
  platform?: PlatformType;
  access?: Record<string, any>;
  __ACCESS__?: Record<string, any>;
}

运行时能力:

  • extensionExtensionConfig,用于外部 UMD 库注入
  • history:路由器模式选择(hash 或 web history)
  • auth:身份验证函数或端点
  • access:权限控制配置
  • remote:云 Provider 场景的远程服务主机

本地服务实现

packages/local/src/service.ts 中的本地服务提供了基于文件系统存储的参考实现,演示了正确的 Provider 扩展模式。

初始化模式

typescript 复制代码
export async function init(body: any, opts: DevToolsOptions) {
  // 1. 加载或创建项目 Schema
  // 2. 初始化存储库层
  // 3. 设置特定于平台的配置
  // 4. 返回已初始化的 ProjectSchema
}

该实现使用来自 packages/local/src/repository/ 的存储库模式层来处理不同的文件类型:

存储库 目的 处理的文件
JsonRepository DSL Schema 持久化 .json 项目、页面、区块文件
VueRepository 源代码文件 .vue 组件文件
StaticRepository 资产管理 图片、字体、样式表
PluginRepository 插件物料加载 远程插件描述符
UniRepository UniApp 配置 manifest.jsonpages.json

💡 存储库模式使得在不修改服务逻辑的情况下切换存储后端成为可能。对于云 Provider,请用基于 HTTP 的数据访问层替换 JSON 存储库,同时保持相同的服务方法签名。

扩展 Provider 系统

自定义 Provider 实现

要创建自定义 Provider,请扩展 Service 抽象类:

typescript 复制代码
import { Service } from "@vtj/core";
import type {
  ProjectSchema,
  BlockSchema,
  VTJConfig,
  HistorySchema,
  HistoryItem,
  MaterialDescription,
  PageFile,
  BlockFile,
} from "@vtj/core";

export class CloudProvider extends Service {
  private client: HttpClient;

  constructor(config: CloudConfig) {
    super();
    this.client = new HttpClient(config);
  }

  async getExtension(): Promise<VTJConfig | undefined> {
    const response = await this.client.get("/api/config");
    return response.data;
  }

  async init(project: Partial<ProjectSchema>): Promise<ProjectSchema> {
    const response = await this.client.post("/api/projects/init", project);
    return response.data;
  }

  async saveProject(project: ProjectSchema): Promise<boolean> {
    await this.client.put(`/api/projects/${project.id}`, project);
    return true;
  }

  // 实现所有抽象方法...
}

Provider 注册

向设计器或渲染器注册自定义 Provider:

typescript 复制代码
import { CloudProvider } from "./providers/cloud-provider";
import { Designer } from "@vtj/designer";

const provider = new CloudProvider({
  baseUrl: "https://api.vtj.example.com",
  apiKey: process.env.API_KEY,
});

const designer = new Designer({
  provider: provider,
  materials: defaultMaterials,
});

详细的 Provider 扩展模式在 扩展 Provider 系统 中有介绍。

异步错误处理

Provider 方法应实现健壮的错误处理:

typescript 复制代码
async getFile(id: string, project?: ProjectSchema): Promise<BlockSchema> {
  try {
    const response = await this.client.get(`/api/files/${id}`);
    return BlockModel.create(response.data);
  } catch (error) {
    if (error.status === 404) {
      throw new Error(`File not found: ${id}`);
    }
    throw new Error(`Failed to retrieve file: ${error.message}`);
  }
}

服务抽象类定义了契约,但并未规定错误处理策略------实现应针对其特定用例选择适当的错误传播模式。

Provider 集成点

设计器集成

设计器使用 Provider 进行:

  • 项目加载 :启动时 init() 检索完整项目 Schema
  • 自动保存 :设计器更改时触发 saveFile(),带有防抖功能
  • 历史记录跟踪 :手动保存时 saveHistoryItem() 捕获快照版本
  • 代码预览genVueContent() 为预览面板生成实时 Vue 代码
  • 物料加载getPluginMaterial() 获取动态组件描述

运行时集成

渲染器通过以下方式使用 Provider API:

  • 配置getExtension() 提供运行时 VTJConfig 设置
  • 动态加载:延迟加载的区块和页面的文件获取
  • 热更新:与 HMR 集成,用于开发时 Schema 更改

类型安全注意事项

Provider API 广泛利用 TypeScript 的类型系统:

  • 泛型约束:针对 Schema 接口类型的存储库实现
  • 可辨识联合NodeFrom 类型使用可辨识联合来保证来源类型安全
  • 字面量类型DataSourceTypeApiMethodPlatformType 使用字符串字面量联合进行编译时验证

扩展 Provider 时,请通过以下方式保持类型安全:

  1. @vtj/core 协议导入所有类型
  2. 使用 typeof 运算符进行 Schema 引用
  3. 使用正确的参数和返回类型实现所有抽象方法
  4. 对照 MaterialDescription 对插件物料导入进行类型检查

跨平台支持

Provider 必须处理特定于平台的差异:

平台 配置 代码生成
Web 带有 axios、路由守卫的 GlobalConfig 标准 Vue 3 语法
H5 移动端优化的 GlobalConfig H5 特定的 CSS 和 API
UniApp 带有 manifest、pages JSON 的 UniConfig UniApp 组件语法和 API

PlatformType 联合类型 ('web' \| 'h5' \| 'uniapp') 驱动 genVueContent 中的条件逻辑和特定于平台的存储库操作,如 packages/local/src/launch/ 中所实现。

相关 API 文档

Provider API 与其他核心系统协同工作:

  • Engine API Reference:引擎生命周期管理和设计器核心 API
  • Renderer API Reference:运行时渲染和组件组合 API
  • Project Structure and File Organization:对应 Schema 结构的物理文件布局

要全面了解 VTJ 的架构模式,请查看 架构概览,它解释了 Provider 抽象层如何实现系统的可扩展性和平台可移植性。

参考资料

相关推荐
HUMHSX27 分钟前
Vue 项目启动全流程解析:从入口文件到全局指令注册与页面渲染
前端·javascript·vue.js
有颜有货38 分钟前
PMC生产排产的4种算法,一次讲清
java·服务器·前端
小虎牙00741 分钟前
Android kotlin图片库Coil源码详解
android·前端
随风一样自由1 小时前
【前端领域】前端开发核心应用场景与落地实践
前端·前端框架
an317421 小时前
弹窗数据流设计的两种高阶架构实践
前端·vue.js·架构
utmhikari1 小时前
【日常随笔】深入回答纯Vibe Coding写后端项目的几个问题
后端·ai编程·vibecoding
ZzT1 小时前
各大 AI 的系统提示词被扒光了,我从里面学到了写指令的功夫
ai编程·claude
谢尔登1 小时前
【React】 状态管理方案
前端·react.js·前端框架
用户2136610035722 小时前
Vue商品详情与放大镜组件
前端·javascript
半个落月2 小时前
从Tapas小Demo理清localStorage、事件与this
前端·javascript