Renderer API 参考

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

核心渲染 API

createRenderer(options)

根据 DSL 模式创建 Vue 组件渲染器,处理组件创建的所有方面,包括状态管理、生命周期钩子和节点渲染。

签名:

function createRenderer(options: CreateRendererOptions): {
  renderer: DefineComponent;
  context: Context;
};

参数:

参数类型默认值描述
VueanyglobalVue用于渲染的 Vue 实例
modeContextModeRuntime渲染模式 (Runtime, Design, Raw, VNode)
dslBlockSchemarequired要渲染的 DSL 模式
componentsRecord<string, any>{}组件注册表
libsRecord<string, any>{}库依赖
apisRecord<string, any>{}API 函数
loaderBlockLoaderdefaultLoader组件加载器函数
windowWindowwindow用于样式注入的 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;
}

关键属性

属性类型描述
__modeContextMode当前渲染模式
__idstring | null块标识符
stateRecord<string, any>响应式状态对象
contextRecord<string, any>执行上下文
$refsRecord<string, any>组件引用
$componentsRecord<string, any>组件注册表
$libsRecord<string, any>库注册表
$apisRecord<string, any>API 注册表
$providerProviderProvider 实例

核心方法

__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

节点渲染 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;

参数:

参数类型默认值描述
dslNodeSchemarequired要渲染的节点模式
contextContextrequired渲染上下文
VueanyglobalVueVue 实例
loaderBlockLoaderdefaultLoader组件加载器
brothersNodeSchema[][]用于 v-if/else-if/else 链的兄弟节点
isBranchbooleanfalse是否为条件链中的分支

支持的功能:

  • 条件渲染: v-if, v-else-if, v-else 指令
  • 列表渲染: 带有自定义迭代器的 v-for
  • 双向绑定: 带修饰符的 v-model
  • 可见性控制: v-show 指令
  • 指令: 通过应用上下文的自定义指令
  • HTML 注入: 用于可信内容的 v-html
  • 表达式绑定: 用于动态属性的 v-bind

指令处理

内置指令

渲染器支持在 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' }
vHtmlHTML 内容{ name: 'vHtml', value: 'state.content' }

getModifiers(modifiers, isToString?)

从指令修饰符中提取并格式化修饰符名称。

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)

创建增强型块加载器,支持异步组件、模式块、基于 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 API

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;
}

关键属性

属性类型描述
modeContextMode当前执行模式
globalsRecord<string, any>全局变量
modulesRecord<string, Function>异步模块加载器
adapterProvideAdapter服务适配器
apisRecord<string, Function>API 函数
dependenciesRecord<string, Function>依赖加载器
materialsRecord<string, Function>物料加载器
libraryRecord<string, any>已加载的库
serviceService核心服务实例
projectProjectSchema当前项目配置
componentsRecord<string, any>组件注册表

核心方法

load(project)

加载并初始化项目,包括依赖、模拟数据、API 和路由。

async load(project: ProjectSchema): Promise<void>

初始化步骤:

  1. 从模块或服务加载项目模式
  2. 加载依赖(Raw 模式)或完整资源(其他模式)
  3. 初始化 Mock.js 配置
  4. 从模式创建 API 接口
  5. 初始化路由(非 uniapp 平台)
  6. 触发就绪事件
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>

资源加载过程:

  1. 解析依赖配置
  2. 加载库脚本和 CSS
  3. 注册内置组件
  4. 加载物料描述
  5. 注册物料组件
initRouter()

使用页面和主页路由初始化 Vue Router。

private initRouter(): void

服务 API

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 为 DSLPromise<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_HOSTVue 实例属性名称['$el', '$emit', '$nextTick', ...]
LIFE_CYCLES_LIST生命周期钩子['beforeCreate', 'created', ...]
BUILT_IN_DIRECTIVES支持的指令['vIf', 'vElseIf', 'vElse', ...]
DATA_TYPESProp 数据类型{ 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 插件

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,
});

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" });

// 访问组件和 API
const 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/…
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com