VTJ Renderer API 完整参考指南
VTJ Renderer API 为开发者提供了一整套完备的工具函数,其核心能力在于将 DSL 模式高效转换为功能完善的 Vue 组件,同时完整管理运行时上下文并贯穿整个渲染生命周期。这份文档专门面向需要集成、扩展或自定义渲染系统的高级开发者——如果你的工作涉及这些场景,以下内容值得仔细研读。

架构概览
渲染系统并非独立运作,而是由多个模块紧密协同完成的。从 DSL 模式到可用的 Vue 组件,整个过程可拆解为几个核心阶段:
graph TDsubgraph InputDSL[DSL Schema]Components[Component Registry]Libs[Libraries]Apis[API Functions]endsubgraph Renderer CoreCreator[createRenderer]Context[Context]NodeRenderer[nodeRender]endsubgraph OutputVNode[VNode]VueComp[Vue Component]endDSL --> CreatorComponents --> CreatorLibs --> CreatorApis --> CreatorCreator --> ContextCreator --> NodeRendererContext --> NodeRendererNodeRenderer --> VNodeVNode --> VueCompProvider[Provider] -.-> CreatorLoader[Loader] -.-> NodeRenderer核心渲染 API
createRenderer(options)
createRenderer 是整个渲染流程的启动入口——它接收 DSL 模式,将组件创建过程中的状态管理、生命周期钩子、节点渲染等各个环节统一处理,最终返回一个可直接注册或渲染的 Vue 组件。
函数签名如下:
function createRenderer(options: CreateRendererOptions): {renderer: DefineComponent;context: Context;};参数说明:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
Vue | any | globalVue | 用于渲染的 Vue 实例对象 |
mode | ContextMode | Runtime | 渲染模式(Runtime, Design, Raw, VNode) |
dsl | BlockSchema | required | 需要渲染的 DSL 模式定义 |
components | Record | {} | 组件注册表映射 |
libs | Record | {} | 外部库依赖集合 |
apis | Record | {} | API 函数集合 |
loader | BlockLoader | defaultLoader | 组件加载器函数 |
window | Window | window | 用于样式注入的 Window 对象 |
返回值包含两个部分:
renderer— 一个完整的 Vue DefineComponent,可直接注册到应用或渲染到模板中context— 负责管理渲染状态的 Context 实例,提供运行时环境
一个典型的调用示例:
const { renderer, context } = createRenderer({Vue,dsl: myBlockSchema,components: { ElButton, ElInput },libs: { lodash: _ },apis: { fetchUser },});app.component("MyBlock", renderer);来源: packages/renderer/src/render/block.ts#L30-L95
上下文 API
Context 类在整个渲染流程中担当“执行环境”的角色,负责表达式解析、函数执行以及作用域管理。你可以将其理解为渲染器的“运行后台”或“运行时容器”。
构造函数
class Context {constructor(options: ContextOptions);}选项接口:
interface ContextOptions {mode: ContextMode;dsl?: BlockSchema;attrs?: ContextAttrs;}关键属性
| 属性 | 类型 | 描述 |
|---|---|---|
__mode | ContextMode | 当前渲染模式标识 |
__id | string | null | 当前块的唯一标识符 |
state | Record | 响应式状态对象 |
context | Record | 执行上下文数据 |
$refs | Record | 组件引用集合 |
$components | Record | 组件注册表映射 |
$libs | Record | 库注册表映射 |
$apis | Record | API 注册表映射 |
$provider | Provider | Provider 实例引用 |
核心方法
__parseExpression(code)
该方法用于解析并求值 JSExpression 节点,所有动态表达式的最终运算都会经过此接口完成。
__parseExpression(code?: JSExpression | JSFunction): any示例:
const value = context.__parseExpression({type: "JSExpression",value: "state.count + 1",});__parseFunction(code)
从 JSFunction 节点中解析出可执行的函数,常用于事件处理、计算属性等场景。
__parseFunction(code?: JSFunction): Function示例:
const handler = context.__parseFunction({type: "JSFunction",value: "(event) => console.log(event)",});__ref(id, ref)
创建引用处理器,用于追踪 DOM 节点和组件实例——其作用类似于 Vue 中的 ref,但更底层且面向渲染引擎。
__ref(id: string | null, ref?: string | Function): (el: any) => void示例:
const refHandler = context.__ref("node-123", "myRef");// 返回函数: (el) => { ... }__clone(context)
当需要在子作用域内渲染(例如 v-for 迭代)时,__clone 会创建一个合并了属性的新上下文,避免污染原始作用域。
__clone(context?: Record<string, any>): Context示例:
const iterationContext = context.__clone({ item: data[0], index: 0 });setup(attrs, Vue)
使用 Vue 实例的属性与生命周期钩子初始化上下文,通常在组件的 setup 阶段被调用。
setup(attrs: Record<string, any>, Vue?: any): void节点渲染 API
nodeRender(dsl, context, Vue, loader, brothers, isBranch)
这是最核心的渲染函数——将单个节点模式转换为 Vue VNode。所有节点(包括组件、原生标签、条件分支等)最终都会经过此函数处理。
签名:
function nodeRender(dsl: NodeSchema,context: Context,Vue?: any,loader?: BlockLoader,brothers?: NodeSchema[],isBranch?: boolean,): VNode | VNode[] | null;参数:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
dsl | NodeSchema | required | 待渲染的节点模式 |
context | Context | required | 渲染上下文实例 |
Vue | any | globalVue | Vue 实例 |
loader | BlockLoader | defaultLoader | 组件加载器 |
brothers | NodeSchema[] | [] | 用于 v-if/else-if/else 链的兄弟节点数组 |
isBranch | boolean | false | 是否为条件链中的分支节点 |
它支持的功能覆盖了 Vue 模板的常见场景:
- 条件渲染: v-if, v-else-if, v-else 指令
- 列表渲染: 带有自定义迭代器的 v-for
- 双向绑定: 带修饰符的 v-model
- 可见性控制: v-show 指令
- 指令: 通过应用上下文实现的自定义指令
- HTML 注入: 用于可信内容的 v-html
- 表达式绑定: 用于动态属性的 v-bind
指令处理
内置指令
渲染器在 constants.ts 中定义了以下内置指令,覆盖了 Vue 中最常用的指令类型:
| 指令 | 描述 | 示例 |
|---|---|---|
vIf | 条件渲染 | { name: 'vIf', value: 'state.visible' } |
vElseIf | 替代条件判断 | { name: 'vElseIf', value: 'state.alt' } |
vElse | 兜底条件 | { name: 'vElse' } |
vFor | 列表循环迭代 | { name: 'vFor', value: 'items', iterator: { item: 'i', index: 'idx' } } |
vModel | 双向数据绑定 | { name: 'vModel', value: 'state.value' } |
vShow | 可见性切换 | { name: 'vShow', value: 'state.visible' } |
vBind | 对象属性绑定 | { name: 'vBind', value: 'state.props' } |
vHtml | HTML 内容注入 | { name: 'vHtml', value: 'state.content' } |
getModifiers(modifiers, isToString?)
从指令修饰符中提取并格式化修饰符名称。例如将 { prevent: true, stop: true } 转换为 ['prevent', 'stop']。
function getModifiers(modifiers: NodeModifiers = {},isToString?: boolean,): string[];示例:
const mods = getModifiers({ prevent: true, stop: true });// 返回: ['prevent', 'stop']块加载器 API
defaultLoader(name, from, Vue)
默认的块加载器实现非常简单——它仅返回组件名称本身,适用于最基础的使用场景。
const defaultLoader: BlockLoader = (name: string) => name;createLoader(opts)
当需要更复杂的加载逻辑时(例如异步组件、根据 ID 或 URL 加载模式、插件加载等),应当使用 createLoader 创建增强型块加载器。
签名:
function createLoader(opts: CreateLoaderOptions): BlockLoader;选项接口:
interface CreateLoaderOptions {getDsl: (id: string) => Promise<BlockSchema | null>;getDslByUrl: (url: string) => Promise<BlockSchema | null>;options: Partial<CreateRendererOptions>;}加载器支持的来源类型:
| 来源类型 | 描述 | 示例 |
|---|---|---|
string | 直接使用组件名称 | 'ElButton' |
Schema | 通过块 ID 加载模式 | { type: 'Schema', id: 'block-123' } |
UrlSchema | 从远程 URL 获取模式 | { type: 'UrlSchema', url: 'https://...' } |
Plugin | 插件形式的组件 | { type: 'Plugin', library: 'MyLib', urls: [...] } |
getPlugin(from, global)
用于从 URL 异步加载插件组件,适合需要动态引入第三方库的场景。
async function getPlugin(from: NodeFromPlugin,global?: any,): Promise<BlockPlugin | null>;示例:
const plugin = await getPlugin({library: "MyPlugin",urls: ["https://cdn.example.com/plugin.css","https://cdn.example.com/plugin.js",],});clearLoaderCache()
清除所有缓存的加载器及队列操作,在需要重置加载状态时非常实用。
function clearLoaderCache(): void;Provider API
Provider 类是整个系统的“总调度”角色,负责项目管理、服务协调、资源加载等核心工作。如果你需要将 VTJ 集成到现有应用中,Provider 会是第一入口。
构造函数
class Provider extends Base {constructor(public options: ProviderOptions)}选项接口:
interface ProviderOptions {service: Service;project?: Partial<ProjectSchema>;modules?: Record<string, () => Promise<any>>;mode?: ContextMode;adapter?: Partial<ProvideAdapter>;router?: Router;dependencies?: Record<string, () => Promise<any>>;materials?: Record<string, () => Promise<any>>;libraryOptions?: Record<string, any>;globals?: Record<string, any>;materialPath?: string;nodeEnv?: NodeEnv;install?: (app: App) => void;routeAppendTo?: RouteRecordName;pageRouteName?: string;routeMeta?: RouteMeta;enhance?: (app: App, provider: Provider) => void;vtjDir?: string;vtjRawDir?: string;enableStaticRoute?: boolean;}关键属性
| 属性 | 类型 | 描述 |
|---|---|---|
mode | ContextMode | 当前执行模式 |
globals | Record | 全局变量存储 |
modules | Record | 异步模块加载函数 |
adapter | ProvideAdapter | 服务适配器实例 |
apis | Record | API 函数集合 |
dependencies | Record | 依赖加载函数 |
materials | Record | 物料加载函数 |
library | Record | 已加载的库对象 |
service | Service | 核心服务实例 |
project | ProjectSchema | 当前项目配置数据 |
components | Record | 组件注册表映射 |
核心方法
load(project)
加载并初始化项目,包括依赖、模拟数据、API 和路由。它是 Provider 的“启动开关”。
async load(project: ProjectSchema): Promise<void>初始化步骤:
- 从模块或服务加载项目模式
- 加载依赖(Raw 模式)或完整资源(其他模式)
- 初始化 Mock.js 配置
- 从模式创建 API 接口
- 初始化路由(非 uniapp 平台)
- 触发就绪事件
createMock(func)
基于 Mock.js 创建模拟数据生成器,便于在开发或测试阶段快速生成假数据。
createMock(func: (...args) => any): (...args) => Promise<any>示例:
const mockUser = provider.createMock(() => ({name: "@name",email: "@email",}));const user = await mockUser();loadDependencies(_window)
加载依赖模块并在全局注册它们,这是 Provider 启动时的重要环节。
private async loadDependencies(_window: any = {}): Promise<void>loadAssets(_window)
加载所有项目资源,包括库脚本、样式表和物料。资源加载流程如下:
private async loadAssets(_window: any = {}): Promise<void>- 解析依赖配置
- 加载库脚本和 CSS
- 注册内置组件
- 加载物料描述
- 注册物料组件
initRouter()
使用页面和主页路由初始化 Vue Router,完成路由表的动态构建。
private initRouter(): void服务 API
BaseService 类
BaseService 提供了所有后端集成方法的基础实现,你只需继承它并传入请求实例即可。
构造函数:
class BaseService implements Service {constructor(public req: IStaticRequest = request)}服务方法
| 方法 | 描述 | 返回值 |
|---|---|---|
getExtension() | 获取扩展配置 | Promise |
init(project) | 初始化项目模式配置 | Promise |
sa veProject(project, type?) | 保存项目数据 | Promise |
sa veMaterials(project, materials) | 保存物料描述信息 | Promise |
sa veFile(file) | 保存块模式定义 | Promise |
getFile(id) | 获取块模式定义 | Promise |
removeFile(id) | 删除文件 | Promise |
sa veHistory(history) | 保存历史记录 | Promise |
getHistory(id) | 获取历史记录 | Promise |
getHistoryItem(fId, id) | 获取历史记录项 | Promise |
sa veHistoryItem(fId, item) | 保存历史记录项 | Promise |
removeHistoryItem(fId, ids) | 删除历史记录项 | Promise |
publish(project) | 发布项目 | Promise |
publishFile(project, file) | 发布文件 | Promise |
genVueContent(project, dsl) | 生成 Vue 代码 | Promise |
parseVue(project, options) | 解析 Vue 为 DSL | Promise |
createRawPage(file) | 创建原始页面 | Promise |
removeRawPage(id) | 删除原始页面 | Promise |
uploadStaticFile(file, projectId) | 上传静态文件 | Promise |
getStaticFiles(projectId) | 获取静态文件列表 | Promise |
removeStaticFile(name, projectId) | 删除静态文件 | Promise |
clearStaticFiles(projectId) | 清空静态文件 | Promise |
getPluginMaterial(from) | 获取插件物料描述 | Promise |
genSource(project) | 生成源代码 | Promise |
辅助函数
createServiceRequest(notify?)
创建一个配置好的 HTTP 请求服务,可以传入一个通知回调用于处理请求状态提示。
function createServiceRequest(notify?: (msg: string) => void): IStaticRequest;常量和枚举
ContextMode 枚举
定义了四种渲染模式,分别对应不同的使用场景:
enum ContextMode {Runtime = "Runtime", // 生产运行时Design = "Design", // 设计器模式Raw = "Raw", // 源代码模式VNode = "VNode", // 虚拟节点模式}NodeEnv 枚举
环境类型定义:
enum NodeEnv {Production = "production",Development = "development",}内置常量
| 常量 | 描述 | 值 |
|---|---|---|
CONTEXT_HOST | Vue 实例属性名称列表 | ['$el', '$emit', '$nextTick', ...] |
LIFE_CYCLES_LIST | 生命周期钩子名称 | ['beforeCreate', 'created', ...] |
BUILT_IN_DIRECTIVES | 渲染器支持的内置指令 | ['vIf', 'vElseIf', 'vElse', ...] |
DATA_TYPES | Prop 数据类型定义 | { String, Number, Boolean, ... } |
PAGE_ROUTE_NAME | 页面路由名称 | 'VtjPage' |
HOMEPAGE_ROUTE_NAME | 主页路由名称 | 'VtjHomepage' |
HTML_TAGS | 原生 HTML 标签列表 | 逗号分隔的标签集合 |
BUILD_IN_TAGS | 内置组件标签 | ['component', 'slot'] |
工具函数
工具函数是渲染器内部常用的辅助方法,理解它们有助于自定义扩展开发。
createDataSources(dataSources, context)
创建数据源函数,支持 mock(基于 Mock.js)和 api(调用已注册的 API 函数,可选转换处理)两种类型。
function createDataSources(dataSources: Record<string, DataSourceSchema>,context: Context,): Record<string, DataSourceHandler>;createProps(props, context)
生成带类型验证和默认值的组件 props 定义,与 Vue 的 props 规范相对应。
function createProps(props: Array<string | BlockProp>,context: Context,): Record<string, PropOptions>;createState(Vue, state, context)
创建响应式状态对象,这是 DSL 中 state 定义的实际实现。
function createState(Vue: any,state: BlockState,context: Context,): Record<string, any>;createComputed(Vue, computedSchema, context)
创建计算属性,每个计算属性本质上是一个 JSFunction。
function createComputed(Vue: any,computedSchema: Record<string, JSFunction>,context: Context,): Record<string, ComputedRef>;createMethods(methods, context)
创建方法函数,同样基于 JSFunction 实现。
function createMethods(methods: Record<string, JSFunction>,context: Context,): Record<string, Function>;setWatches(Vue, watches, context)
为响应式数据设置监听器,对应 Vue 的 watch 选项。
function setWatches(Vue: any, watches: BlockWatch[], context: Context): void;createLifeCycles(lifeCycle, context)
创建生命周期钩子处理器,将 DSL 中定义的生命周期函数映射到 Vue 的钩子机制。
function createLifeCycles(lifeCycle: Record<string, JSFunction>,context: Context,): Record<string, Function>;插件系统
Access 插件
Access 插件提供了身份验证和授权功能,你可以通过它实现基于角色的页面或组件访问控制。
获取位置: packages/renderer/src/plugins/access.ts
集成示例
下面通过三个典型场景,展示如何在实际项目中运用这些 API。
基础组件渲染
import { createRenderer } from "@vtj/renderer";import * as Vue from "vue";const { renderer } = createRenderer({Vue,dsl: {id: "my-block",name: "MyBlock",state: { count: 0 },nodes: [{id: "button-1",name: "el-button",props: { type: "primary" },events: {click: { type: "JSFunction", value: "state.count++" },},children: `Count: ${"state.count"}`,},],},components: { ElButton },});// 在 Vue 应用中注册app.component("MyComponent", renderer);动态块加载
import { createLoader, createRenderer } from "@vtj/renderer";const loader = createLoader({async getDsl(id) {const response = await fetch(`/api/blocks/${id}`);return response.json();},async getDslByUrl(url) {const response = await fetch(url);return response.json();},options: {Vue,components: { ElButton },loader: null, // 将递归设置},});// 在渲染器中使用加载器const { renderer } = createRenderer({Vue,dsl: parentSchema,loader,});Provider 集成
import { Provider } from "@vtj/renderer";import { BaseService, createServiceRequest } from "@vtj/renderer";const provider = new Provider({service: new BaseService(createServiceRequest()),mode: ContextMode.Runtime,project: { id: "my-project" },router,dependencies: {ElementPlus: () => import("element-plus"),},materials: {MyMaterials: () => import("./materials"),},});// 加载项目await provider.load({ id: "my-project" });// 访问组件和 APIconst components = provider.components;const apis = provider.apis;API 参考摘要
| 模块 | 用途 | 主要导出 |
|---|---|---|
render/block | 组件渲染 | createRenderer, createDataSources |
render/context | 上下文管理 | Context 类 |
render/node | 节点渲染 | nodeRender, getModifiers |
render/loader | 块加载 | createLoader, getPlugin, clearLoaderCache |
provider | 项目管理 | Provider 类, providerKey |
services/base | 服务层 | BaseService, createServiceRequest |
constants | 常量定义 | ContextMode, BUILT_IN_DIRECTIVES, DATA_TYPES |
utils | 工具函数 | isJSExpression, isJSFunction, parseDeps |
plugins | 插件 | 访问控制插件 |
hooks | 钩子 | 与遮罩相关的钩子 |
相关文档
- Engine API Reference: 了解与渲染器协同工作的引擎核心 API
- Provider API Reference: 深入了解 provider 系统及服务集成
- Renderer System and Runtime: 理解渲染器架构与生命周期
- DSL Schema and Data Models: 用于渲染的 DSL 模式结构
参考资料
- 官方文档:vtj.pro/
- 在线平台:app.vtj.pro/
- 开源仓库:gitee.com/newgateway/…
