金闪闪
44.31M · 2026-03-26
VTJ Renderer API 提供了一套全面的工具,用于将 DSL 模式渲染为 Vue 组件,管理运行时上下文以及处理完整的渲染生命周期。本文档专为需要集成、扩展或自定义渲染系统的高级开发者设计。
渲染系统由多个相互连接的模块组成,它们协同工作将 DSL 模式转换为功能性的 Vue 组件:
graph TD
subgraph Input
DSL[DSL Schema]
Components[Component Registry]
Libs[Libraries]
Apis[API Functions]
end
subgraph Renderer Core
Creator[createRenderer]
Context[Context]
NodeRenderer[nodeRender]
end
subgraph Output
VNode[VNode]
VueComp[Vue Component]
end
DSL --> Creator
Components --> Creator
Libs --> Creator
Apis --> Creator
Creator --> Context
Creator --> NodeRenderer
Context --> NodeRenderer
NodeRenderer --> VNode
VNode --> VueComp
Provider[Provider] -.-> Creator
Loader[Loader] -.-> NodeRenderer
createRenderer(options)根据 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<string, any> | {} | 组件注册表 |
libs | Record<string, any> | {} | 库依赖 |
apis | Record<string, any> | {} | API 函数 |
loader | BlockLoader | defaultLoader | 组件加载器函数 |
window | Window | window | 用于样式注入的 Window 对象 |
返回值:
renderer: 准备好进行注册或渲染的 Vue DefineComponentcontext: 管理渲染状态的 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
Context 类管理渲染过程中的执行环境,处理表达式解析、函数执行和作用域管理。
class Context {
constructor(options: ContextOptions);
}
选项:
interface ContextOptions {
mode: ContextMode;
dsl?: BlockSchema;
attrs?: ContextAttrs;
}
| 属性 | 类型 | 描述 |
|---|---|---|
__mode | ContextMode | 当前渲染模式 |
__id | string | null | 块标识符 |
state | Record<string, any> | 响应式状态对象 |
context | Record<string, any> | 执行上下文 |
$refs | Record<string, any> | 组件引用 |
$components | Record<string, any> | 组件注册表 |
$libs | Record<string, any> | 库注册表 |
$apis | Record<string, any> | 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 节点和组件实例。
__ref(id: string | null, ref?: string | Function): (el: any) => void
示例:
const refHandler = context.__ref("node-123", "myRef");
// 返回函数: (el) => { ... }
__clone(context)创建一个合并了属性的新上下文,用于作用域渲染(例如 v-for 迭代)。
__clone(context?: Record<string, any>): Context
示例:
const iterationContext = context.__clone({ item: data[0], index: 0 });
setup(attrs, Vue)使用 Vue 实例属性和生命周期钩子初始化上下文。
setup(attrs: Record<string, any>, Vue?: any): void
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 | 是否为条件链中的分支 |
支持的功能:
渲染器支持在 constants.ts 中定义的这些内置指令:
| 指令 | 描述 | 示例 |
|---|---|---|
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?)从指令修饰符中提取并格式化修饰符名称。
function getModifiers(
modifiers: NodeModifiers = {},
isToString?: boolean,
): string[];
示例:
const mods = getModifiers({ prevent: true, stop: true });
// 返回: ['prevent', 'stop']
defaultLoader(name, from, Vue)默认组件加载器,仅返回组件名称。
const defaultLoader: BlockLoader = (name: string) => name;
createLoader(opts)创建增强型块加载器,支持异步组件、模式块、基于 URL 的模式和插件。
签名:
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 类是项目管理、服务协调和资源加载的核心协调器。
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<string, any> | 全局变量 |
modules | Record<string, Function> | 异步模块加载器 |
adapter | ProvideAdapter | 服务适配器 |
apis | Record<string, Function> | API 函数 |
dependencies | Record<string, Function> | 依赖加载器 |
materials | Record<string, Function> | 物料加载器 |
library | Record<string, any> | 已加载的库 |
service | Service | 核心服务实例 |
project | ProjectSchema | 当前项目配置 |
components | Record<string, any> | 组件注册表 |
load(project)加载并初始化项目,包括依赖、模拟数据、API 和路由。
async load(project: ProjectSchema): Promise<void>
初始化步骤:
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)加载依赖模块并在全局注册它们。
private async loadDependencies(_window: any = {}): Promise<void>
loadAssets(_window)加载所有项目资源,包括库、样式和物料。
private async loadAssets(_window: any = {}): Promise<void>
资源加载过程:
initRouter()使用页面和主页路由初始化 Vue Router。
private initRouter(): void
BaseService 类提供所有后端集成方法的基础服务实现。
构造函数:
class BaseService implements Service {
constructor(public req: IStaticRequest = request)
}
| 方法 | 描述 | 返回值 |
|---|---|---|
getExtension() | 获取扩展配置 | Promise<VTJConfig> |
init(project) | 初始化项目模式 | Promise<ProjectSchema> |
saveProject(project, type?) | 保存项目 | Promise<boolean> |
saveMaterials(project, materials) | 保存物料描述 | Promise<boolean> |
saveFile(file) | 保存块模式 | Promise<boolean> |
getFile(id) | 获取块模式 | Promise<BlockSchema> |
removeFile(id) | 删除文件 | Promise<boolean> |
saveHistory(history) | 保存历史记录 | Promise<boolean> |
getHistory(id) | 获取历史记录 | Promise<HistorySchema> |
getHistoryItem(fId, id) | 获取历史记录项 | Promise<HistoryItem> |
saveHistoryItem(fId, item) | 保存历史记录项 | Promise<boolean> |
removeHistoryItem(fId, ids) | 删除历史记录项 | Promise<boolean> |
publish(project) | 发布项目 | Promise<boolean> |
publishFile(project, file) | 发布文件 | Promise<boolean> |
genVueContent(project, dsl) | 生成 Vue 代码 | Promise<string> |
parseVue(project, options) | 解析 Vue 为 DSL | Promise<BlockSchema> |
createRawPage(file) | 创建原始页面 | Promise<boolean> |
removeRawPage(id) | 删除原始页面 | Promise<boolean> |
uploadStaticFile(file, projectId) | 上传静态文件 | Promise<StaticFileInfo> |
getStaticFiles(projectId) | 获取静态文件 | Promise<StaticFileInfo[]> |
removeStaticFile(name, projectId) | 删除静态文件 | Promise<boolean> |
clearStaticFiles(projectId) | 清除静态文件 | Promise<boolean> |
getPluginMaterial(from) | 获取插件物料 | Promise<MaterialDescription> |
genSource(project) | 生成源代码 | Promise<string> |
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)创建用于 API 调用和模拟数据的数据源函数。
function createDataSources(
dataSources: Record<string, DataSourceSchema>,
context: Context,
): Record<string, DataSourceHandler>;
数据源类型:
mock: 使用 Mock.js 生成数据api: 调用注册的 API 函数,并可选进行转换createProps(props, context)创建具有类型验证和默认值的组件 props 定义。
function createProps(
props: Array<string | BlockProp>,
context: Context,
): Record<string, PropOptions>;
createState(Vue, state, context)创建响应式状态对象。
function createState(
Vue: any,
state: BlockState,
context: Context,
): Record<string, any>;
createComputed(Vue, computedSchema, context)创建计算属性。
function createComputed(
Vue: any,
computedSchema: Record<string, JSFunction>,
context: Context,
): Record<string, ComputedRef>;
createMethods(methods, context)创建方法函数。
function createMethods(
methods: Record<string, JSFunction>,
context: Context,
): Record<string, Function>;
setWatches(Vue, watches, context)为响应式数据设置监视器。
function setWatches(Vue: any, watches: BlockWatch[], context: Context): void;
createLifeCycles(lifeCycle, context)创建生命周期钩子处理器。
function createLifeCycles(
lifeCycle: Record<string, JSFunction>,
context: Context,
): Record<string, Function>;
Access 插件提供身份验证和授权功能。
获取位置: packages/renderer/src/plugins/access.ts
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,
});
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" });
// 访问组件和 API
const components = provider.components;
const apis = provider.apis;
| 模块 | 用途 | 主要导出 |
|---|---|---|
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 | 钩子 | 与遮罩相关的钩子 |