MermaidBlockNode (Component)
MermaidBlockNode 提供一个易于使用且可扩展的 Mermaid 渲染器,适用于需要在文档中内嵌交互式 Mermaid 图的场景。组件支持渐进式渲染、源码/预览切换、复制源码、导出 SVG,以及伪全屏查看(带缩放与拖拽)。
Props(关键)
node: any— Mermaid 代码节点(必须)isDark?: boolean— 暗色模式开关loading?: boolean— 初始加载占位maxHeight?: string | null— 最大高度estimatedPreviewHeightPx?: number— Mermaid 完成渲染前预留的首屏 preview 高度;通过MarkdownRender渲染 Mermaid 围栏时会自动填入isStrict?: boolean— 默认true;开启securityLevel: 'strict'+ DOMPurify,并禁用 HTML labels。只有可信图表确实需要 Mermaid HTML labels 时才设为false。- Header/按钮控制(全部可选,默认
true):showHeader/showModeToggle/showCopyButton/showExportButton/showFullscreenButton/showCollapseButton/showZoomControls/showTooltips
enableWheelZoom?: boolean— 开启 Ctrl/Cmd + 滚轮缩放(默认false)- 超时(毫秒):
workerTimeoutMs/parseTimeoutMs/renderTimeoutMs/fullRenderTimeoutMs(默认1400/1800/2500/4000) - 流式调优:
renderDebounceMs/contentStableDelayMs/previewPollDelayMs/previewPollMaxDelayMs/previewPollMaxAttempts
Slots
header-left— 替换左侧(默认是 Mermaid 图标 + 标签)header-center— 替换中间区域(默认 preview/source 切换)header-right— 替换右侧操作按钮(完整接管默认按钮)
Emits
组件发出的事件都使用统一的 MermaidBlockEvent 对象,支持 preventDefault() 来阻止组件默认行为:
copy— 点击复制按钮,处理签名:(ev: MermaidBlockEvent<{ type: 'copy'; text: string }>)(调用ev.preventDefault()可阻止组件默认的复制到剪贴板与 “Copied” 状态)export— 导出按钮点击,处理签名:(ev: MermaidBlockEvent<{ type: 'export' }>)openModal— 请求打开 pseudo-fullscreen,处理签名:(ev: MermaidBlockEvent<{ type: 'open-modal' }>)(组件内部 emit 名称为openModal)toggleMode— 切换source | preview,处理签名:(target: 'source' | 'preview', ev: MermaidBlockEvent<{ type: 'toggle-mode'; target: 'source' | 'preview' }>)(组件内部 emit 名称为toggleMode)
拦截示例
完全替换组件默认导出行为:
vue
<script setup lang="ts">
import type { MermaidBlockEvent } from 'markstream-vue'
import { MermaidBlockNode } from 'markstream-vue'
function onExport(ev: any /* MermaidBlockEvent */) {
ev.preventDefault()
// 组件在事件对象中暴露了 svgElement,直接使用它更方便
const svgEl = ev.svgElement as SVGElement | null
if (!svgEl) {
console.warn('No svg element available')
return
}
const svgString = new XMLSerializer().serializeToString(svgEl)
uploadSvg(svgString)
}
</script>
<template>
<MermaidBlockNode :node="node" @export="onExport" />
</template>注意:
export/openModal事件的事件对象现已同时包含svgElement(DOM 节点)和svgString(已序列化的 SVG 字符串),任选其一使用更方便。
Slot 示例:完全接管右侧操作按钮
vue
<MermaidBlockNode :node="node" :showExportButton="false">
<template #header-right>
<button @click="downloadSvg">Download</button>
<button @click="openCustomModal">Open custom modal</button>
</template>
</MermaidBlockNode>推荐用法
- 如果你要实现自定义导出/上传,最佳做法是:在
export监听器中preventDefault(),并在监听回调中直接从组件渲染的 DOM 中读取svg。 - 如果你想要完全替换头部的 UI,使用
header-*插槽并把相应show*props 设为false来隐藏默认按钮。 - Mermaid 严格模式默认开启,因此用户/LLM 图表会经过 SVG 清理并禁用 HTML labels。只有可信图表需要宽松 Mermaid 渲染时,才设置
:is-strict="false"。
对可信图表恢复 loose 模式
如果某个可信 Mermaid 图依赖 HTML labels,或者依赖旧的 loose 模式渲染结果,可以按组件粒度显式关闭 strict,而不是把更安全的默认值整体改回去:
vue
<script setup lang="ts">
import { MermaidBlockNode } from 'markstream-vue'
const node = {
type: 'code_block',
language: 'mermaid',
code: 'flowchart TD\n A["<b>可信</b><br/>label"] --> B',
raw: 'flowchart TD\n A["<b>可信</b><br/>label"] --> B',
}
</script>
<template>
<MermaidBlockNode :node="node" :is-strict="false" />
</template>只有 Mermaid 源内容可信时才建议这样做;用户内容或 LLM 输出仍建议保留默认 strict。
参考
- 覆盖
MermaidBlockNode(在MarkdownRender中使用setCustomComponents)的示例(中文):覆盖 MermaidBlockNode(MarkdownRender 示例)
Playground 示例:仓库包含一个可运行的 playground 页面演示如何拦截 export 并上传 ev.svgString —— 路由: mermaid-export-demo (文件:playground/src/pages/mermaid-export-demo.vue)。