2.0.0
Skip to content

代码示例 ​

用于渲染 LLM 返回的流式 Markdown。下面按 @ant-design/x-markdown@2.0.0 的「代码示例」排列。每一则都是 Vue 已经实现的能力。

可编辑的预览在 在线体验,和基础用法是同一块输入框。

基础用法 ​

Hello World

Welcome to XMarkdown!

  • Item 1
  • Item 2
  • Item 3
const a = 1;
基础用法

markdown 基础语法渲染。文本框里改内容会立刻重绘。

流式处理 ​

Status: idle
流式处理

未完成内容逐段送入,结束后关闭 streaming。

插件使用 ​

plugin

Ship the TODO before Friday.

插件使用

plugins 的 transform 在 marked 之前改写字符串。公式、高亮、Mermaid 见对应插件页。

自定义组件 ​

Custom Blue Title

Normal H2

Paragraph with bold and italic.

自定义组件

components 把标签映射成自己的 Vue 组件。

公式 ​

Pythagoras: .

公式

Latex 插件。

代码高亮 ​

A fenced block picks up the language class:

ts
export const answer = 42;

Inline const x = 1 stays a plain code tag.

代码高亮

HighlightCode。

Mermaid ​

```mermaid
graph TD
  A[Start] --> B[Answer]
```
Mermaid

围栏语言是 mermaid 时交给 Mermaid。

主题 ​

Theme sample

Body text with a link.

  • one
  • two

Theme sample

Body text with a link.

  • one
  • two
主题

light / dark 类名。

自定义标记 tokenizer ​

Level 1 Heading

Level 2 Heading

Level 3 Heading

Level 4 Heading

自定义标记 tokenizer

用 marked extensions 把 % 标题解析成 heading。

标记处理 walkTokens ​

Please check: Invalid link

标记处理 walkTokens

用 config.walkTokens 改写或拦截 token。

渲染前处理 renderer ​

🚀 Render Code Text

<html><form><button>Test</button><form></html>
渲染前处理 renderer

自定义 marked renderer,再配合 components 替换标签。

中文链接处理 ​

Untreated

Treated

中文链接处理

裸 URL 后紧跟中文或括号时,截断链接并保留后缀文本。

XSS 防御 ​

Cross-Site Scripting (XSS) Attack Vectors

1. Stored XSS (Persistent XSS)

2. Reflected XSS (Non-persistent XSS)

Malicious Link)

3. DOM-based XSS

4. Attribute-based XSS

5. Script Tag Injection

6. Event Handler XSS

Test Image

7. JavaScript Protocol XSS

Click Here

8. SVG Vector XSS

9. Form Input XSS

10. CSS Injection XSS

Test Content

11. Data URI XSS

12. Mouse Event XSS

Hover over this text

13. Button Tag XSS

14. Nested script evasion

XSS 防御

DOMPurify 会去掉危险脚本、事件属性和 javascript: 链接。

流式语法 ​

Markdown Source
Click Re-Render to start
Rendered Output
流式语法

未闭合的链接、表格等先占位,不按半截 Markdown 解析。

流式动画 ​

流式动画

streaming.enableAnimation 让新出现的段落淡入。

新标签页打开链接 ​

openLinksInNewTab enabled

Open links in a new tab

Reference link

This is a reference-style link.

Default (same tab)

Open links in a new tab

Reference link

This is a reference-style link.

新标签页打开链接

openLinksInNewTab 给链接加上 target="_blank"。

思考过程 ​

Check the constraint, then answer.

The answer is 42.

思考过程

自定义标签交给 Think。

API ​

属性说明类型默认值
content要渲染的 Markdown 内容string-
childrenMarkdown 内容,content 的别名string-
components用自定义 Vue 组件替换 HTML / 自定义标签,详见 组件总览Record<string, Component>-
paragraphTag段落使用的 HTML 标签。自定义组件含块级元素时可改成 div,避免非法嵌套string'p'
streaming流式渲染配置,见 流式语法boolean | StreamingOption-
configmarked 解析与扩展配置MarkedExtension{ gfm: true }
plugins兼容旧写法:带 transform(content) 的对象会在解析前改写字符串;优先用 config + marked extensionsany[]-
openLinksInNewTab是否给所有 a 标签加上 target="_blank"(以及 rel="noopener noreferrer")booleanfalse
dompurifyConfigDOMPurify 配置,用于 HTML 消毒与 XSS 防护DOMPurify.Config-
className根节点额外 CSS 类名string-
rootClassNameclassName 的别名string-
style根节点内联样式CSSProperties-
prefixClsCSS 类名前缀覆盖string-

StreamingOption ​

属性说明类型默认值
hasNextChunk后面是否还有 chunk。为 false 时刷新缓存并完成渲染booleanfalse
enableAnimation为块级元素(p、li、h1–h4)启用文字淡入booleanfalse
animationConfig文字出现动画配置AnimationConfig{ fadeDuration: 200, easing: 'ease-in-out' }
incompleteMarkdownComponentMap未完成语法对应的自定义组件名。流式输出遇到未闭合的链接、表格、HTML 等时,可用占位 / loading 组件包裹片段Partial<Record<Exclude<StreamCacheTokenType, 'text'>, string>>{}

AnimationConfig ​

属性说明类型默认值
fadeDuration淡入动画时长(毫秒)number200
easing缓动函数string'ease-in-out'

ComponentProps ​

自定义 components 映射组件收到的入参:

属性说明类型默认值
domNode解析后的 DOM 节点信息(标签名、属性、子节点结构)DOMNode-
streamStatus流式状态:loading 表示该块仍在输出,done 表示已闭合。目前主要覆盖 HTML 与围栏代码;缩进代码块没有明确结束符,始终为 done。code 也可读 data-state'loading' | 'done'-
block仅 code:data-block="true" 时为块级代码boolean-
children组件包裹的内容VNode[] | string-
其余标准 HTML 属性(href、title、class / className 等)与自定义 data-*Record<string, any>-

StreamCacheTokenType ​

与源码 StreamCacheTokenType 枚举一致(注意是 html,不是文档旧稿里的 heading / xml):

ts
type StreamCacheTokenType =
  | 'text' // 纯文本
  | 'link' // 链接 [text](url)
  | 'image' // 图片 ![alt](src)
  | 'html' // HTML / 自定义标签 <tag>
  | 'emphasis' // 强调 *斜体* **粗体**
  | 'list' // 列表 - + *
  | 'table'; // 表格 | header | content |

hasNextChunk 为 true 时,未完成 token 会转成 incomplete-<token>(可用 incompleteMarkdownComponentMap 改名),原文放在 data-raw(encodeURIComponent)。text 不生成占位标签。

FAQ ​

Components 与 config marked extensions 的区别 ​

config marked extensions(解析扩展) ​

config 里的 extensions 在 Markdown → HTML 阶段生效:

  • 阶段:Markdown 解析
  • 作用:识别并转换特殊语法
  • 例子:把 [^1] 脚注语法变成 <footnote>1</footnote>
  • 场景:扩展 Markdown 语法
ts
const footnoteExtension = {
  name: 'footnote',
  level: 'inline',
  start(src) {
    return src.match(/\[\^/)?.index;
  },
  tokenizer(src) {
    const rule = /^\[\^([^\]]+)\]/;
    const match = rule.exec(src);
    if (match) {
      return {
        type: 'footnote',
        raw: match[0],
        text: match[1],
      };
    }
  },
  renderer(token) {
    return `<footnote>${token.text}</footnote>`;
  },
};

// <XMarkdown content="脚注示例[^1]" :config="{ extensions: [footnoteExtension] }" />

components(组件替换) ​

components 在 HTML → VNode 阶段把标签换成 Vue 组件:

  • 阶段:渲染
  • 作用:替换 HTML / 自定义标签
  • 例子:把 <footnote>1</footnote> 换成可点击的脚注组件
  • 场景:自定义样式与交互

完整示例见 自定义插件。