这次来点狠的:用 Vue 3 把 AI 的“碎片 Markdown”渲染得又快又稳(Monaco 实时更新 + Mermaid 渐进绘图)

在做 AI 应用或协同编辑时,你八成遇到过这些痛点:

  • 模型在"打字",Markdown 半截一坨,渲染器直接崩溃
  • 代码块动不动几千行,实时更新卡得怀疑人生
  • Mermaid 图不合法就整块失效,用户看到一片空白
  • 内容一边流一边更新,DOM 抖动、滚动乱跳

我做了一个专门为"流式 Markdown"场景优化的组件库------vue-renderer-markdown,它能把这些"坏情况"处理得优雅、顺滑、还很快。

为什么它不一样

  • 为流式而生:兼容"半截 Markdown/半截代码块/半截 Mermaid"的中间态,边流边稳
  • 高性能 Monaco:大块代码的增量更新,不卡 UI,编辑/预览都丝滑
  • 渐进式 Mermaid:一旦语法"刚好可解析",先画出来;后续流入再迭代完善,避免整块空白
  • 完整 Markdown 能力:表格、公式、emoji、复选框、代码块......该有的都有
  • 实时更新友好:尽量少的重排重绘,几乎没有 DOM 抖动
  • TypeScript First:完备类型定义 + 智能提示
  • 零配置引入:开箱即用,Vue 3 项目即插即用
  • 数学公式极速渲染(KaTeX):支持行内/块级公式,流式输入也能稳健增量更新;半截公式不"炸屏",后续补齐自动完善显示

一分钟上手

安装

可任选你的包管理工具(以下是可选命令,仅供参考):

npm 复制代码
# 推荐
pnpm add vue-renderer-markdown

# 同时安装常见 peer 依赖(按需取舍)
pnpm add vue @iconify/vue @vueuse/core katex mermaid vue-use-monaco
# npm
npm i vue-renderer-markdown vue @iconify/vue @vueuse/core katex mermaid vue-use-monaco
# yarn
yarn add vue-renderer-markdown vue @iconify/vue @vueuse/core katex mermaid vue-use-monaco

基础用法:就是一个普通的 Vue 组件

vue 复制代码
<script setup lang="ts">
import MarkdownRender from 'vue-renderer-markdown'

const markdownContent = `
# Hello Vue Markdown

这是一段**Markdown**,支持:
- 列表
- [x] 复选框
- :tada: Emoji
`
</script>

<template>
  <MarkdownRender :content="markdownContent" />
</template>

流式渲染(AI 输出、实时更新场景)

vue 复制代码
<script setup lang="ts">
import { ref } from 'vue'
import MarkdownRender from 'vue-renderer-markdown'

const content = ref('')
const full = `# 流式内容\n\n这段文字会"逐字"出现...`

let i = 0
const timer = setInterval(() => {
  if (i < full.length) {
    content.value += full[i++]
  } else {
    clearInterval(timer)
  }
}, 40)
</script>

<template>
  <MarkdownRender :content="content" />
</template>

实战 1:Mermaid 渐进式绘图(边流边画)

Mermaid 的常见问题是"语法半截 -> 图形全挂"。这里我们做了渐进式解析:一旦内容达到"可画"的下限,就先画出来;后续流入再增量更新。

vue 复制代码
<script setup lang="ts">
import { ref } from 'vue'
import MarkdownRender from 'vue-renderer-markdown'

const content = ref('')
const steps = [
  '```mermaid\n',
  'graph TD\n',
  'A[Start]-->B{Valid?}\n',
  'B -- Yes --> C[Render]\n',
  'B -- No  --> D[Wait]\n',
  '```\n',
]

let i = 0
const id = setInterval(() => {
  content.value += steps[i] || ''
  i++
  if (i >= steps.length) clearInterval(id)
}, 120)
</script>

<template>
  <MarkdownRender :content="content" />
</template>

实战 2:Monaco 大代码块的"丝滑流更"

大代码块每次整体重渲染是灾难。vue-renderer-markdown 针对这类场景做了"增量更新 + 合理切分",在内容不断流入时保持 UI 流畅。

Vite 项目推荐配合 vite-plugin-monaco-editor-esm,打包 Worker 更稳(Windows 尤其):

vue 复制代码
// vite.config.ts
import path from 'node:path'
import monacoEditorPlugin from 'vite-plugin-monaco-editor-esm'

export default {
  plugins: [
    monacoEditorPlugin({
      languageWorkers: [
        'editorWorkerService',
        'typescript',
        'css',
        'html',
        'json',
      ],
      customDistPath(root, outDir, base) {
        return path.resolve(outDir, 'monacoeditorwork')
      },
    }),
  ],
}

然后像上面一样用 <MarkdownRender :content="..."> 渲染带代码块的 Markdown;当内容流式追加时,你会发现 Monaco 的高亮和结构更新不会阻塞主线程。

实战 3:数学公式极速渲染(KaTeX)

KaTeX 渲染快、稳定,非常适合 AI 场景的"边流边出"。本库内置对数学节点的处理,配好 peer 依赖即可用。

  • 依赖提示:请在你的项目中安装 katex(本库会处理 KaTeX CSS 的加载;如需自定义主题样式,可自行覆盖)。

基础用法(行内 + 块级)

vue 复制代码
<script setup lang="ts">
import MarkdownRender from 'vue-renderer-markdown'

const markdownContent = `
这是行内公式:$E = mc^2$

这是块级公式:
$$
\\int_{-\\infty}^{\\infty} e^{-x^2} \\, dx = \\sqrt{\\pi}
$$
`
</script>

<template>
  <MarkdownRender :content="markdownContent" />
</template>

流式渲染(逐步补齐的公式)

当 AI 一段段吐词时,公式也可以渐进显示:一旦达到可解析的下限就先展示,后续补齐再增量更新,不会整块空白或抖动。

vue 复制代码
<script setup lang="ts">
import { ref } from 'vue'
import MarkdownRender from 'vue-renderer-markdown'

const content = ref('')
const steps = [
  '$$\\n',
  '\\\\sum_{i=1}^n i = ',
  '\\\\frac{n(n+1)}{2}',
  '\\n$$\\n',
]

let i = 0
const id = setInterval(() => {
  content.value += steps[i] || ''
  i++
  if (i >= steps.length) clearInterval(id)
}, 120)
</script>

<template>
  <MarkdownRender :content="content" />
</template>

它为什么快?

  • 增量解析:不是"全量重跑解析器",而是只处理变动的片段
  • DOM 最小化更新:节点级别的精准更新,避免重排/重绘风暴
  • 动画帧调度:把昂贵任务放进 requestAnimationFrame,滚动/输入更顺滑
  • 内存优化:长时间流式渲染也不"越跑越重",自动清理废弃状态
  • 容错/降级:半截语法、异常 token、临时不合法内容都能稳稳接住
  • 数学节点增量更新:内容未完整时先稳态呈现,补齐后迅速完善,不阻塞其他内容渲染

适合哪些场景?

  • AI Chat / Copilot 类应用:模型边说边写、Markdown 边渲染
  • 文档/博客编辑器的实时预览:对大代码块/长文档友好
  • 数据/日志可视化:Mermaid/表格/高亮混合流式输出
  • 协同编辑:多人同时修改,内容频繁变动

API 简要

  • 组件:MarkdownRender

  • 关键 Props

    • content: string(渲染 Markdown 字符串)
    • nodes: BaseNode[](也可传 AST 节点)
    • customComponents: Record<string, any>(在 Markdown 中渲染自定义组件)
  • 模板中使用时注意驼峰转短横线,例如 customComponents => custom-components

生态与依赖

  • 同时安装必要的 peer 依赖(根据你启用的功能按需选择),例如:vue、@iconify/vue、@vueuse/core、katex、mermaid、vue-use-monaco
  • Monaco 仅在需要编辑器/大代码预览时安装
  • Mermaid 仅在需要绘图时安装

在线体验 & 下一步

如果你正在做 AI 应用、云 IDE、或任何需要"边流边渲染"的工具,这个库会让你少掉很多不必要的性能坑。欢迎 Star、试用、提 Issue/PR,一起把"流式 Markdown 渲染"这件小事做到极致。

相关推荐
云枫晖2 小时前
JS核心知识-事件循环
前端·javascript
eason_fan2 小时前
Git 大小写敏感性问题:一次组件重命名引发的CI构建失败
前端·javascript
无羡仙3 小时前
JavaScript 迭代器
前端
XiaoSong3 小时前
从未有过如此丝滑的React Native开发体验:EAS开发构建完全指南
前端·react.js
掘金者阿豪3 小时前
打通KingbaseES与MyBatis:一篇详尽的Java数据持久化实践指南
前端·后端
RoyLin4 小时前
TypeScript设计模式:原型模式
前端·后端·node.js
我是天龙_绍4 小时前
vue Composables 组合式函数
前端
zjjuejin4 小时前
Maven项目的核心蓝图:POM文件
前端·maven
小气小憩4 小时前
“暗战”百度搜索页:Monica悬浮球被“围剿”,一场AI Agent与传统巨头的流量攻防战
前端·人工智能