e0a5f57793
Vendor the rebranded BoosAPI Desktop client (Tauri + Vue) into metapi as a monorepo subdirectory under desktop/. Source only — node_modules, dist, Cargo target and the upstream .git history are excluded. desktop/ keeps its own independent Cargo workspace (desktop/src-tauri with crates/*); it is not part of the backend boosapi crate, so a `cargo check` at the metapi root still compiles only the backend. Build the desktop app from desktop/src-tauri per desktop/README.md. Note: app icons are still placeholder assets pending the final BoosAPI logo. The updater signing keys live outside the repo and are not included.
4.6 KiB
4.6 KiB
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— 开启securityLevel: 'strict'+ DOMPurify,并禁用 HTML labels;用于渲染不可信的 Mermaid 输入(例如用户/LLM 生成的内容),防止<script>、javascript:链接或内联事件落入最终 SVG- 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)
拦截示例
完全替换组件默认导出行为:
<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 示例:完全接管右侧操作按钮
<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 或任何不可信来源,建议加上
:is-strict="true",组件会对 SVG 进行清理并禁用 HTML labels,从而堵住恶意<script>或javascript:链接注入的风险。
参考
- 覆盖
MermaidBlockNode(在MarkdownRender中使用setCustomComponents)的示例(中文):覆盖 MermaidBlockNode(MarkdownRender 示例)
Playground 示例:仓库包含一个可运行的 playground 页面演示如何拦截 export 并上传 ev.svgString —— 路由: mermaid-export-demo (文件:playground/src/pages/mermaid-export-demo.vue)。