稀土掘金技术社区 09月28日 09:53
AI应用如何处理和渲染Markdown表格数据
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文探讨了AI应用中处理Markdown表格数据的挑战与解决方案。当AI返回大量表格数据时,若直接使用v-html进行全量渲染,将失去Vue的DOM更新优化和组件化能力。文章提出通过解析Markdown文本为嵌套树状结构,并利用Vue的插槽和自定义渲染器(VkRendererTemplate),实现对表格等特定Markdown元素的灵活替换和交互式增强。这种策略使得开发者能够轻松集成第三方库,如ECharts和Mermaid,并保持响应式更新,从而高效地处理各类复杂的AI生成内容。

💡 **Markdown全量渲染的局限性**:直接使用`v-html`渲染AI返回的Markdown文本(如表格数据)会导致Vue的diff算法优化失效,并且无法利用Vue组件的能力。这使得分页、筛选等交互操作难以实现,限制了用户体验。

🌳 **Markdown解析与树状结构构建**:为了实现更灵活的渲染,文章提出将Markdown文本通过markdown-it等工具解析成tokens,并进一步构建成与Vue vDOM对应的嵌套树状结构。每个解析后的节点会添加`templateType`字段,为后续自定义渲染奠定基础。

🧩 **策略渲染与组件化集成**:通过Vue的插槽和`VkRendererTemplate`组件,可以根据`templateType`为不同的Markdown元素(如表格、图表、流程图)定义自定义渲染逻辑。这使得开发者能够用任意Vue组件替换默认渲染,轻松集成第三方库,并实现动态交互。

🚀 **vunk-markdown的核心功能**:该组件库的核心在于“解析”和“策略渲染”。它封装了常见的渲染策略,如默认渲染、ECharts图表渲染和Mermaid流程图渲染,并允许用户轻松扩展自定义渲染器,以适应多样化的AI应用需求。

修仙的人 2025-09-28 09:01 重庆

点击关注公众号,技术干货及时达!

想象一个这样的场景, 你的 AI 应用通过知识库查询,为你返回了几十条 Table 数据。产品希望用户能够对 Table 数据执行分页、筛选等操作。

你很容易想到使用你熟知的 UI 组件库, 来渲染 AI 返回的 Table 数据。效果看起来就像这样:

这个库的地址在 

github.com/EralChen/vunk-markdown .

不过,你也不需要非常着急的使用它,在这篇文章中我将向你揭露一些技术细节,以便你来应对,像 「ECharts 图表渲染」「流程图」「大纲」「地图」 等一切业务中可能存在的需求。认真看完,希望你会有所收获.

简单实现存在的问题众所周知, AI 倾向于使用 Markdown 文本数据流向客户端传递信息。 一个简单的渲染,就像:

<script setup>// ... 省略其他配置;const md = MarkdownIt({    highlight,})const htmlText = computedAsync(async () => {  return md.render(props.source)}, '')</script><template>   <div v-html="htmlText"></div></template><!-- 使用 --><MarkdownRender :source="source"></MarkdownRender>
v-html 是一个全量渲染的过程, 并且他仅仅渲染 html 字符串。

这意味着,你不再享有 Vue DOM 更新时的 diff 算法优化, 同时也失去了使用 Vue 组件的权力。

你所期望的调用方式以替换 Table 这个需求为例,你可以想象最直观的调用方式,就像:

<!-- 这是一个简单用例, 实际实现考虑到扩展性, 会略有不同 --><MarkdownRender :source="source">    <template #table="{ data, columns }">      <MyTables :data="data" :columns="columns" />    </template></MarkdownRender>
如果将数据收集到对应的插槽的参数中,那么我们就能轻松使用任意组件库,来替换原有标签.

解析无论你使用何种 Markdown 工具 (markdown-it、marked、remark), 要想在渲染之前提取数据, 必然绕不开对 markdown 原文本的解析.

这个过程需要封装在 MarkdownRender 中, 不被使用端感知.

这里仅以 markdown-it 为例, 你可以在 markdown-it demo 查看解析结果

要想让 markdown 解析成 Vue 组件关键是构建嵌套树状结构, 与 vDOM 结构对应

「Markdown 文本」 → 「markdown-it tokens」(扁平数组)

「markdown-it tokens」 → 「嵌套树状结构」

「树状结构」 → 「Vue 组件渲染」(由渲染器处理)

// setupconst renderItems = computed(() => tokensToTree(  md.parse(props.source, {})))// template<VkRenderer :source="renderItems">   <slot /></VkRenderer>
一个完整的解析后的数据结构示例 -- h1 标签结构, 如下:

{    "templateType""GroupToken",    "tag""h1",    "open": {}, // Markdown Tokon 省略    "close": {}, //  Markdown Tokon 省略    "children": [        {            "type""inline",            "tag""",            "attrs"null,            "map": [                0,                1            ],            "nesting"0,            "level"1,            "children": [                {                    "type""text",                    "tag""",                    "attrs"null,                    "map"null,                    "nesting"0,                    "level"0,                    "children"null,                    "content""标题一级",                    "markup""",                    "info""",                    "meta"null,                    "block"false,                    "hidden"false,                    "templateType""text"                }            ],            "content""标题一级",            "markup""",            "info""",            "meta"null,            "block"true,            "hidden"false,            "templateType""inline"        }    ]}
而我们唯一要做的, 就是将解析后的结果交给用户, 让用户自定义渲染采用的组件.

我想这就是全部! 是我们最终的目标!

策略渲染如果你认真阅读, 解析章节, 那么你将发现

const renderItems = computed(() => tokensToTree( md.parse(props.source, {}) )) // template <VkRenderer :source="renderItems"> <slot /> </VkRenderer>
template 中的 VkRenderer 接收的source 正是解析后的树状结构.

再回看解析后的 json 数据, 解析的过程中, 每个 item 都被添加了 templateType 字段.

如果有一个组件能够匹配 templateType 字段, 来渲染内容. 那么我们将轻松实现

「替换默认渲染」:为任何 Markdown 元素自定义渲染逻辑

「增强交互性」:将静态内容转换为交互式组件

「集成第三方库」:集成语法高亮、图表等功能

「保持响应式」:利用 Vue 的响应式系统实现动态更新

而你只需要将策略写在组件的默认插槽内, 使用起来就像:

<script lang="ts" setup>import { VkMarkdown, VkRendererTemplate } from '@vunk/markdown'import { computed, ref } from 'vue'const source = `# Hello, Markdown!This is a simple example of using **Markdown** in a Vue component.`</script><template><VkMarkdown    :source="source"  >          <VkRendererTemplate type="text">        <template #default={ raw }>            {{ raw.content }}        </template>    </VkRendererTemplate>        <VkRendererTemplate type="GroupToken">      <!-- 省略实现 -->    </VkRendererTemplate>        <!-- 省略 inline 实现 --></VkMarkdown></template>
组件库所做的事很感谢你能看到这里, 如你所见 「解析」 和 「策略渲染」 就是 vunk-markdown 的核心.

对于常见的渲染策略, 组件库中做了封装

TemplatesDefault 用于渲染常规 Markdown 内容

TemplateEcharts 用于 Echarts 图表渲染

TemplateMermaid 用于 mermaid 流程图渲染

同时你可以, 在 example 中看到更多自定义渲染

AI编程资讯AI编码专区指南:

https://aicoding.juejin.cn/aicoding

~

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

AI应用 Markdown渲染 Vue.js 表格处理 组件化 vunk-markdown ECharts Mermaid 前端开发 AI编码
相关文章