Render AI-Generated Tables in Vue: Mastering vunk-markdown Parsing & Strategy Rendering
This article explains how to transform AI-generated markdown tables into interactive Vue components by parsing markdown with vunk-markdown, customizing rendering strategies, and integrating UI libraries for features like pagination, filtering, charts, and diagrams, while preserving Vue’s reactivity and performance.
Introduction
Imagine a scenario where your AI application queries a knowledge base and returns dozens of rows of table data. The product expects users to be able to paginate, filter, and otherwise manipulate that table data.
You might instinctively reach for a UI component library to render the AI‑returned table, resulting in a view like the one below:
The library is hosted at github.com/EralChen/vunk-markdown , but you don’t need to rush into using it. In this article we will reveal several technical details so you can handle requirements such as ECharts chart rendering , flowcharts , outlines , maps , and any other business needs.
Problems with a Simple Implementation
It is well known that AI tends to transmit information to the client as a markdown text stream. A naïve rendering might look like this:
<script setup>
// ... omitted other configuration;
const md = MarkdownIt({
highlight,
})
const htmlText = computedAsync(
async () => {
return md.render(props.source)
},
''
)
</script>
<template>
<div v-html="htmlText"></div>
</template>
<!-- usage -->
<MarkdownRender :source="source">
</MarkdownRender>The v-html directive performs a full‑text render of the html string, which means you lose Vue’s diff‑algorithm optimizations and the ability to use Vue components.
Desired Invocation Method
Using the table example, an intuitive call could be:
<!-- This is a simple example; actual implementation may differ for extensibility -->
<MarkdownRender :source="source">
<template #table="{ data, columns }">
<MyTables :data="data" :columns="columns" />
</template>
</MarkdownRender>If the data is collected into the corresponding slot parameters, you can easily replace the original tags with any component library.
Parsing
No matter which markdown tool you use (markdown‑it, marked, remark), extracting data before rendering inevitably requires parsing the original markdown text.
This process must be encapsulated inside MarkdownRender so that the consumer does not notice it.
Below is a screenshot of the parsing result (markdown‑it demo):
To convert markdown into Vue components you need to build a nested tree structure that corresponds to the vDOM:
Markdown text → markdown‑it tokens (flat array)
markdown‑it tokens → nested tree structure
Tree structure → Vue component rendering (handled by the renderer)
// setup
const renderItems = computed(() =>
tokensToTree(md.parse(props.source, {}))
)
// template
<VkRenderer :source="renderItems">
<slot />
</VkRenderer>A complete parsed data‑structure example for an h1 tag:
{
"templateType": "GroupToken",
"tag": "h1",
"open": {},
"close": {},
"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"
}
]
}The only thing left is to hand the parsed result to the user so they can choose which component renders each piece of content.
Strategy Rendering
If you read the parsing section carefully, you will notice the following pattern:
const renderItems = computed(() => tokensToTree(md.parse(props.source, {}))
// template
<VkRenderer :source="renderItems"><slot /></VkRenderer>In the template, the VkRenderer receives the parsed tree as its source prop.
During parsing, each item is given a templateType field. If a component can match this templateType, it can render the content, enabling:
Replace default rendering : customize rendering logic for any markdown element
Enhance interactivity : turn static content into interactive components
Integrate third‑party libraries : add syntax highlighting, charts, etc.
Maintain reactivity : leverage Vue’s reactive system for dynamic updates
You only need to place your strategy inside the component’s default slot, for example:
<script setup lang="ts">
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">
<!-- implementation omitted -->
</VkRendererTemplate>
</VkMarkdown>
</template>What the Component Library Does
As you have seen, parsing and strategy rendering are the core of vunk-markdown.
The library provides default implementations for common rendering strategies:
TemplatesDefault – renders regular markdown content.
TemplateEcharts – renders ECharts charts.
TemplateMermaid – renders Mermaid flowcharts.
More custom rendering examples can be found in the library’s example directory.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
