Skip to content

AiRichContent

AiRichContent 用于渲染 AI 输出的结构化富内容文档。它把一次回复拆成多个 block,可以同时包含 Markdown、图片、脑图、知识图谱、图表、表格、图标、文件卡片、代码块、HTML 预览和业务自定义 renderer。

如果只需要普通 Markdown,请优先使用 AiXMarkdown。当需要流式输出、单块重新生成、可编辑结构化结果或工具调用结果渲染时,再使用 AiRichContent

使用场景

  • AI 分析报告、Agent 工具结果、知识问答引用来源。
  • 混合 Markdown、图表、表格、文件和可视化区块的结果页。
  • Vue2 存量系统通过 Lingxi SDK 挂载 Vue3 富内容组件。
  • 业务自定义 renderer 接入内部图表、卡片或审批结果。

基础用法

vue
<script setup lang="ts">
import { ref } from 'vue'
import { AiRichContent } from '@zhiyongui/lingxi-ui'
import '@zhiyongui/lingxi-ui/ai-rich-content/style.css'

const document = ref({
  version: '1.0',
  mode: 'editable',
  blocks: [
    {
      id: 'summary',
      type: 'markdown',
      title: '结论摘要',
      content: '### 本周分析\n- 转化率提升 12%\n- 响应时长下降 18%',
    },
    {
      id: 'table',
      type: 'table',
      title: '核心指标',
      data: {
        columns: [
          { key: 'name', label: '指标' },
          { key: 'value', label: '数值', align: 'right', format: 'number' },
        ],
        rows: [
          { name: '访问量', value: 12000 },
          { name: '转化数', value: 860 },
        ],
      },
    },
  ],
})
</script>

<template>
  <AiRichContent v-model="document" editable />
</template>

Vue2 SDK 用法

Vue2 页面通过 SDK 挂载 Vue3 组件。update:modelValue 在 Vue2 中要用 'onUpdate:modelValue' 传入;页面销毁时必须 unmount

js
import { mountLingxiComponent } from '@zhiyongui/lingxi-ui/sdk'
import { AiRichContent } from '@zhiyongui/lingxi-ui'
import '@zhiyongui/lingxi-ui/ai-rich-content/style.css'

export default {
  data() {
    return {
      instance: null,
      richDocument: {
        version: '1.0',
        mode: 'editable',
        blocks: [],
      },
    }
  },
  mounted() {
    this.instance = mountLingxiComponent(AiRichContent, {
      container: this.$refs.richContent,
      props: {
        modelValue: this.richDocument,
        editable: true,
        'onUpdate:modelValue': (nextDocument) => {
          this.richDocument = nextDocument
        },
        onAction: (action, block) => {
          console.log(action, block.id)
        },
      },
    })
  },
  beforeDestroy() {
    this.instance && this.instance.unmount()
  },
  methods: {
    appendText(content) {
      this.instance.callMethod('applyDelta', {
        type: 'block_delta',
        id: 'answer',
        content,
      })
    },
    setReadonly(readonly) {
      this.instance.update({ readonly })
    },
  },
}
html
<div ref="richContent"></div>

Vue2 完整示例

示例包含只读/编辑切换、流式 delta、Markdown、图片、脑图、知识图谱、图表、表格、代码和文件卡片。

只读模式

readonly 会强制关闭编辑能力;document.mode = 'readonly' 也会进入只读状态。

vue
<AiRichContent
  :model-value="document"
  readonly
  :features="{ chart: true, table: true, file: true }"
/>

可编辑模式

设置 editable 后,组件会显示块级工具栏,并允许内置可视化 block 打开轻量编辑器。业务侧可以监听 update:blockdelete:blockmove:blockregenerate 持久化变化。

vue
<AiRichContent
  v-model="document"
  editable
  @update:block="saveBlock"
  @regenerate="regenerateBlock"
/>

流式 Delta 示例

applyDelta(delta) 用于 AI 流式输出,不需要业务直接操作 DOM。

ts
richRef.value.applyDelta({
  type: 'block_start',
  block: {
    id: 'answer',
    type: 'markdown',
    content: '',
    loading: true,
  },
})

richRef.value.applyDelta({
  type: 'block_delta',
  id: 'answer',
  content: '\n正在生成内容...',
})

richRef.value.applyDelta({
  type: 'block_progress',
  id: 'answer',
  progress: 60,
  message: 'Generating',
})

richRef.value.applyDelta({
  type: 'block_end',
  id: 'answer',
})

自定义 Renderer

自定义 renderer 会收到 blockdocumenteditableselectedcontext。推荐通过 context.updateBlockcontext.emitActioncontext.reportError 与外层交互。

ts
import { h } from 'vue'

const renderers = {
  metric: {
    props: ['block', 'context'],
    setup(props) {
      return () => h('button', {
        onClick: () => props.context.emitAction({ key: 'drilldown', label: 'Drilldown' }),
      }, `${props.block.data.label}: ${props.block.data.value}`)
    },
  },
}
vue
<AiRichContent
  v-model="document"
  :renderers="renderers"
/>

输入协议

组件支持三种输入,内部统一归一化为 AiRichContentDocument

ts
type AiRichContentValue =
  | string
  | AiRichContentBlock[]
  | AiRichContentDocument

字符串输入会作为 Markdown 解析,并识别 lingxi:* 代码块。

md
### 分析结果

```lingxi:chart
{
  "title": { "text": "访问趋势" },
  "xAxis": { "type": "category", "data": ["Mon", "Tue"] },
  "yAxis": { "type": "value" },
  "series": [{ "type": "line", "data": [120, 160] }]
}
```

Block 类型

类型用途
markdownMarkdown 文本,由 AiXMarkdown 渲染。
text普通纯文本。
image图片和 caption。
mindmap思维导图结构。
knowledge-graph节点和边组成的知识图谱。
excel结构化工作簿,由 AiExcelEditor 渲染。
chart基于 ECharts 渲染图表配置。
table结构化表格。
iconSVG、URL 或文本图标。
file文件卡片或文件列表。
code代码块,内置复制和折叠。
html-previewiframe HTML 预览。
custom业务自定义 block。

Props

属性类型默认值说明
modelValuestring | AiRichContentBlock[] | AiRichContentDocumentundefined富内容输入。
editablebooleanfalse是否启用编辑工具栏和编辑器。
readonlybooleanfalse是否强制只读。
renderersRecord<string, AiRichContentRenderer>undefined自定义 block renderer。
featuresPartial<Record<AiRichContentBlockType, boolean>>undefined控制内置 block 类型开关。
fallbackRendererAiRichContentRendererundefined不支持类型的兜底 renderer。
confirmDeletebooleantrue删除 block 前是否弹出确认。
iframeSandboxstring''html-preview iframe sandbox。
assetUrlValidator(url, block) => booleanundefined图片、图标、文件 URL 校验函数。
emptyTextstring'No rich content'空状态文案。

Events

事件参数说明
update:modelValuedocument文档更新。
update:blockblock, context单个 block 更新。
insert:blockblock, context插入 block。
delete:blockblock, context删除 block。
move:blockpayload移动 block。
select:blockblock | null选择 block。
actionaction, block, context工具栏或 renderer 动作。
regenerateblock, context请求重新生成。
errorerror, context渲染或操作异常。

Slots

当前无公开 slot。业务扩展应通过 renderersfallbackRenderer 实现,以保证 Vue2 SDK 与 Vue3 直用行为一致。

Exposes

方法参数说明
getDocument()-获取当前文档。
setDocument(value)AiRichContentValue设置文档。
applyDelta(delta)AiRichContentDelta应用流式 delta。
getBlock(id)string获取指定 block。
updateBlock(id, patch)string, Partial<AiRichContentBlock> | AiRichContentBlock更新指定 block。
moveBlock(id, to)string, number移动指定 block。
focusBlock(id)string聚焦指定 block。
exportDocument()-导出当前文档对象。

样式入口

接入方式样式
全量包import '@zhiyongui/lingxi-ui/style.css'
按需包import '@zhiyongui/lingxi-ui/ai-rich-content/style.css'
IIFE加载 lingxi-visualization.css

常见问题

为什么普通聊天页不建议默认引入 AiRichContent?

AiRichContent 会连接图表、脑图、图谱、表格等重型能力。普通聊天只需要 Markdown 时应使用 AiXMarkdown 或聊天 IIFE。

如何限制可渲染的 block?

使用 features 关闭不允许的类型,并提供 fallbackRenderer 展示安全兜底。

HTML 预览安全吗?

html-preview 使用 iframe。生产环境建议显式设置 iframeSandbox,并通过 assetUrlValidator 限制图片、文件和图标 URL。