核心概念
一句话理解:你给一段 JSON,A2UI 帮你渲染成页面。用户点了按钮,你收到通知,处理完再返回一段 JSON 更新页面。
举个例子:后端返回这样一段 JSON ——
json
{ "id": "btn", "component": "WButton", "type": "primary", "child": "btn_text" },
{ "id": "btn_text", "component": "Text", "text": "提交申请" }A2UI 就会在页面上渲染出一个蓝色按钮,上面写着"提交申请"。
5 分钟上手
把下面的代码复制到一个 .vue 文件里就能跑。这是一个最简单的完整例子:
就这么简单:配置 → 创建处理器 → 发 JSON → 页面就出来了。
三种使用模式
根据你的场景,A2UI 有三种用法:
| 模式 | 一句话说明 | 适合谁 | 详细文档 |
|---|---|---|---|
| Processor 模式 | 你自己控制:收 JSON、渲染、响应事件 | AI 对话、需要精细控制 | 下文 + Processor API |
| processMessages2 模式 | 一次调用搞定:渲染 + 自动调后端 API | 前端页面直接对接后端 | 调用后端 API |
| Window 监听模式 | 用原生 addEventListener 监听事件 | 非 Vue 环境 | Window 事件监听 |
TIP
三种模式可以混用。比如用 processMessages2 渲染页面,同时用 processor.onEvent 做额外处理。
模式一:Processor 模式(最灵活,推荐)
完整代码放在一个 Vue 组件的 <script setup> 里:
typescript
import {
A2UISurface,
provideA2UI,
useMessageProcessor,
DEFAULT_CATALOG,
} from 'win-design-a2ui-vue';
// ─── 初始化 ─────────────────────────────────────
provideA2UI({ catalog: DEFAULT_CATALOG, theme: {} });
const processor = useMessageProcessor();
// ─── 监听事件(可选,按需注册)──────────────────
// 页面创建时,设置初始数据
processor.onSurfaceCreated((surfaceId, surface, apis) => {
apis.updateDataModel(surfaceId, '/patientName', ''); // 初始化一个空字符串
});
// 页面渲染完成后,可以操作组件(比如禁用某个按钮)
processor.onSurfaceUpdated((surfaceId, surface, apis) => {
apis.updateComponentProp(surfaceId, 'btn_submit', 'disabled', false);
});
// 用户点击按钮时触发(必须调用 resolve,否则页面会卡住)
processor.onEvent((event) => {
const { name, type, surfaceId } = event.message.userAction;
if (name === 'submit') {
// 读取用户输入的数据
const patientName = processor.getDataValue(surfaceId, '/patientName');
console.log('用户输入了:', patientName);
// 处理完后调用 resolve,可以传入新的 JSON 来更新页面
event.resolve([
{
version: 'v0.9',
updateDataModel: { surfaceId, path: '/result', value: '提交成功' },
},
]);
} else {
event.resolve([]); // 不需要更新页面,传空数组即可
}
});
// ─── 发送消息,渲染页面 ─────────────────────────
processor.processMessages([
{
version: 'v0.9',
createSurface: { surfaceId: 'main', catalogId: 'default' },
},
{
version: 'v0.9',
updateComponents: {
surfaceId: 'main',
components: [
{
id: 'input_name',
component: 'WInput',
placeholder: '请输入患者姓名',
modelValue: { path: '/patientName' },
},
{
id: 'btn_submit',
component: 'WButton',
type: 'primary',
action: { event: { name: 'submit', type: 'click' } },
child: 'btn_text',
},
{ id: 'btn_text', component: 'Text', text: '提交' },
],
},
},
]);
// ─── 绑定到模板 ─────────────────────────────────
const surfaces = processor.getSurfaces();模板部分:
html
<A2UISurface
v-for="[id, surface] in surfaces"
:key="id"
:surface-id="id"
:surface="surface"
/>模式二:processMessages2 模式(最省事)
如果你的页面需要:打开时从后端加载数据 + 按钮点击自动调后端接口。用这个模式不用手动写事件监听和 API 调用。
typescript
processor.processMessages2(
// 会话信息(会自动传给后端)
{ userId: 'user_001', token: 'xxx' },
// 业务参数(会传给初始加载接口)
{ orderId: 'ORD-20260430-001' },
// 页面描述(组件 + 初始数据)
{
surfaceId: 'api-demo',
components: [
{
id: 'input_name',
component: 'WInput',
placeholder: '请输入姓名',
modelValue: { path: '/name' },
},
{
id: 'btn_submit',
component: 'WButton',
type: 'primary',
action: { event: { name: 'submit', api: { url: '/api/submit' } } },
child: 'btn_text',
},
{ id: 'btn_text', component: 'Text', text: '提交' },
],
data: { name: '张三' }, // 渲染前先设置这些数据
loadEventHandler: { url: '/api/loadData' }, // 渲染后自动调这个接口加载数据
},
// 后端返回后的回调
(actionInfo, interfaceInfo) => {
if (actionInfo.actionType === 'load') {
console.log('页面加载完成,后端返回:', interfaceInfo);
} else {
console.log('按钮点击后后端返回:', interfaceInfo);
}
},
);详细说明见 调用后端 API
模式三:Window 监听模式(通用)
如果你不在 Vue 环境中(比如原生 JS、React),可以用 window.addEventListener 监听事件:
typescript
// 监听用户操作(必须调用 respond,否则页面会卡住)
window.addEventListener('win-design-a2ui-event', (e) => {
const { message, respond, getDataValue, updateDataModel } = (e as CustomEvent)
.detail;
if (message.userAction.surfaceId !== 'my_surface') return; // 需要自己判断是哪个页面
if (message.userAction.name === 'submit') {
const name = getDataValue(message.userAction.surfaceId, '/userName');
console.log('用户输入了:', name);
respond([]); // 处理完必须调用
} else {
respond([]); // 不处理也必须调用
}
});WARNING
Window 监听模式是全局的,如果页面上有多个 A2UI 实例,需要手动检查 surfaceId 来区分。推荐在 Vue 项目中使用 Processor 模式。
processor 所有方法速查
| 方法 | 干什么 | 详细说明 |
|---|---|---|
processMessages(messages) | 处理 JSON 消息,渲染页面 | Processor API |
processMessages2(...) | 一次调用完成渲染 + 对接后端 API | 调用后端 API |
getSurfaces() | 拿到所有页面的 Map,绑定到模板 | Processor API |
getDataValue(surfaceId, path) | 读取某个数据(比如用户输入) | Processor API |
onSurfaceCreated(callback) | 页面创建时的回调 | 事件监听 |
onSurfaceUpdated(callback) | 页面渲染完成时的回调 | 事件监听 |
onEvent(callback) | 用户操作的回调(点击、输入等) | 事件监听 |
dispatch(surfaceId, message) | 手动触发一个事件 | Processor API |
clearSurfaces(surfaceId?) | 清除页面 | Processor API |
getFormInstance(formId) | 获取表单实例,用来校验/重置 | Processor API |
getPangoEditorInstance(domId?) | 获取富文本编辑器实例 | Processor API |
getPangoEditorParams(domId?) | 获取富文本编辑器的保存数据 | Processor API |
完整 API 参考见 Processor API 参考
渲染管线:JSON 是怎么变成页面的
你写的 JSON 消息
│
▼
processor.processMessages(messages)
│
├── createSurface → 创建一个"画布"(Surface)
│
├── updateComponents → 在画布上放组件(按钮、输入框等)
│
├── updateDataModel → 设置数据(比如输入框的默认值)
│
▼
Surface Map(你可以理解为:一个放着组件的画布集合)
│
▼ 模板中用 <A2UISurface> 渲染
│
▼
页面上出现按钮、输入框、表格...关键概念:
| 名词 | 白话解释 |
|---|---|
| Surface | 一个"画布"。一个页面可以有一个或多个画布,每个画布独立管理自己的组件和数据 |
| Component | 组件,比如按钮、输入框、表格。在 JSON 中用 "component": "WButton" 指定 |
| DataModel | 数据模型,像一个全局变量表。组件可以通过 { "path": "/userName" } 绑定数据 |
| Catalog | 组件目录,一个映射表:"WButton" → WButton.vue 组件 |
| Processor | 消息处理器,你通过它发消息、监听事件、读写数据 |
三个核心角色
Config(配置)
通过 provideA2UI 注入全局配置,所有子组件共享:
ts
import { provideA2UI, DEFAULT_CATALOG } from 'win-design-a2ui-vue';
provideA2UI({
catalog: DEFAULT_CATALOG, // 组件目录(用哪些组件)
theme: {}, // 主题(留空即可)
});自定义 Catalog
如果需要注册自定义组件,可以扩展默认 Catalog:
ts
import { DEFAULT_CATALOG } from 'win-design-a2ui-vue';
import MyCustomCard from './MyCustomCard.vue';
const myCatalog = {
...DEFAULT_CATALOG,
my_card: MyCustomCard, // 注册自定义组件
};
provideA2UI({ catalog: myCatalog, theme: {} });之后 JSON 中就可以使用 "component": "my_card" 来渲染你的自定义组件。
MessageProcessor(消息处理器)
你跟 A2UI 打交道的唯一入口。通过它发消息、监听事件、读写数据。
ts
const processor = useMessageProcessor();所有方法见上方的 processor 所有方法速查 表格
Catalog(组件目录)
组件名 → Vue 组件 的映射表,决定了 JSON 中 "component": "WButton" 最终渲染成什么。
ts
import { DEFAULT_CATALOG } from 'win-design-a2ui-vue';
// DEFAULT_CATALOG 已经注册了所有内置组件:WButton, WText, WInput, WInputNumber, WSelect, WCascader, WDatePicker, WTimePicker, WTimeSelect, WTable ...Markdown 渲染
useMarkdownRenderer 提供将 Markdown 字符串安全渲染为 HTML 的能力(基于 markdown-it + dompurify):
ts
import { useMarkdownRenderer } from 'win-design-a2ui-vue';
const renderer = useMarkdownRenderer();
const html = renderer.render('**Hello** _World_');
// → '<p><strong>Hello</strong> <em>World</em></p>'所有输出均经过 DOMPurify 净化,防止 XSS 注入。
下一步
- JSON 消息格式:JSON 怎么写?有哪些字段?
- Processor API 参考:所有方法(含事件监听)的详细说明
- 调用后端 API:怎么让按钮自动调后端接口?
- Window 事件监听:非 Vue 环境下的事件监听