Mermaid 与 PlantUML 使用指南:用文本快速生成流程图、时序图和类图

Mermaid 与 PlantUML 使用指南:从入门到写出可维护的技术图表

如果你经常写技术文档、设计说明、接口文档或者架构方案,应该会遇到一个问题:图一旦多起来,就会越来越难维护。

传统画图工具适合一次性出图,但不太适合频繁修改。流程一变、接口一改、模块一重构,往往就得重新拖拽、对齐、导出。相比之下,Mermaid 和 PlantUML 这种"用文本生成图表"的方式更适合开发团队:它们可以纳入 Git、可以直接放进文档、可以复用,也更容易随着项目一起演进。

这篇文章会用教程式的方式,带你了解:

  • Mermaid 和 PlantUML 分别是什么
  • Mermaid 为什么会在 Markdown 中自动渲染
  • 如何同时展示 Mermaid 渲染效果和源码
  • Mermaid 与 PlantUML 的常见写法和适用场景
  • 实际项目里该怎么选

1. 为什么要用文本画图

文本画图最大的价值,不是"更炫",而是"更容易维护"。

它有几个非常实际的优势:

  • 图表内容可以直接纳入 Git 版本管理
  • 修改成本低,适合频繁迭代的项目
  • 可以直接嵌入 Markdown、Wiki、文档站点
  • 团队成员可以像审查代码一样审查图表
  • 图表不再是一次性图片,而是可持续维护的文档资产

如果你的工作里经常要写 README、接口说明、架构设计、系统流程,那么这类工具通常会比拖拽式画图工具更省心。

2. Mermaid 是什么

Mermaid 是一种基于文本语法生成图表的工具,常见于 Markdown 文档、知识库、静态文档站点以及部分编辑器预览环境中。

它的特点很适合入门:

  • 语法比较简单,上手快
  • 对流程图、时序图支持很好
  • 非常适合写在 README 和技术文档里
  • 和 Markdown 生态结合得很自然

先看一个最小示例。

2.1 渲染效果

#mermaid-svg-TafhnQtCqDFa0ijP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TafhnQtCqDFa0ijP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TafhnQtCqDFa0ijP .error-icon{fill:#552222;}#mermaid-svg-TafhnQtCqDFa0ijP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TafhnQtCqDFa0ijP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TafhnQtCqDFa0ijP .marker.cross{stroke:#333333;}#mermaid-svg-TafhnQtCqDFa0ijP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TafhnQtCqDFa0ijP p{margin:0;}#mermaid-svg-TafhnQtCqDFa0ijP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster-label text{fill:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster-label span{color:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster-label span p{background-color:transparent;}#mermaid-svg-TafhnQtCqDFa0ijP .label text,#mermaid-svg-TafhnQtCqDFa0ijP span{fill:#333;color:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .node rect,#mermaid-svg-TafhnQtCqDFa0ijP .node circle,#mermaid-svg-TafhnQtCqDFa0ijP .node ellipse,#mermaid-svg-TafhnQtCqDFa0ijP .node polygon,#mermaid-svg-TafhnQtCqDFa0ijP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TafhnQtCqDFa0ijP .rough-node .label text,#mermaid-svg-TafhnQtCqDFa0ijP .node .label text,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape .label,#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape .label{text-anchor:middle;}#mermaid-svg-TafhnQtCqDFa0ijP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TafhnQtCqDFa0ijP .rough-node .label,#mermaid-svg-TafhnQtCqDFa0ijP .node .label,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape .label,#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape .label{text-align:center;}#mermaid-svg-TafhnQtCqDFa0ijP .node.clickable{cursor:pointer;}#mermaid-svg-TafhnQtCqDFa0ijP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TafhnQtCqDFa0ijP .arrowheadPath{fill:#333333;}#mermaid-svg-TafhnQtCqDFa0ijP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TafhnQtCqDFa0ijP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TafhnQtCqDFa0ijP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TafhnQtCqDFa0ijP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TafhnQtCqDFa0ijP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TafhnQtCqDFa0ijP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TafhnQtCqDFa0ijP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster text{fill:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster span{color:#333;}#mermaid-svg-TafhnQtCqDFa0ijP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TafhnQtCqDFa0ijP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TafhnQtCqDFa0ijP rect.text{fill:none;stroke-width:0;}#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape p,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape .label rect,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TafhnQtCqDFa0ijP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TafhnQtCqDFa0ijP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TafhnQtCqDFa0ijP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

用户登录
认证成功?
进入首页
提示错误信息

2.2 对应语法

markdown 复制代码
```mermaid
flowchart TD
    A[用户登录] --> B{认证成功?}
    B -->|是| C[进入首页]
    B -->|否| D[提示错误信息]
    D --> A
```

2.3 这一段语法怎么看

  • flowchart TD 表示这是一个流程图,方向是从上到下
  • A[用户登录] 表示一个矩形节点
  • B{认证成功?} 表示一个判断节点
  • --> 表示连接关系
  • |是||否| 表示边上的文字说明

如果你是第一次接触 Mermaid,建议先记住一个思路:先写节点,再写连接,最后补方向和说明文字。

3. Mermaid 为什么会在 Markdown 中自动渲染

很多人第一次看到 Mermaid 时都会疑惑:明明我写的是代码块,为什么页面上显示的是图?

原因其实很简单:Markdown 本身不会渲染 Mermaid,真正起作用的是"支持 Mermaid 的渲染环境"。

也就是说:

  • 普通 Markdown 语法只负责保存文本结构
  • 当预览器、编辑器或文档平台识别到代码块类型是 mermaid
  • 它会把这段文本交给 Mermaid 引擎渲染成图表

例如这段代码:

markdown 复制代码
```mermaid
flowchart LR
    A[前端] --> B[网关]
    B --> C[服务A]
    B --> D[服务B]
```

在不同环境里的表现可能不一样:

  • 在普通 Markdown 查看器里,可能只会显示源码
  • 在支持 Mermaid 的预览器里,会直接显示成图

常见支持场景包括:

  • GitHub 的部分 Markdown 场景
  • VuePress / VitePress / Docusaurus 文档站点
  • 一些 Wiki 或知识库系统
  • Typora、Obsidian 等支持 Mermaid 的编辑器
  • 安装 Mermaid 扩展后的 VS Code 预览环境

4. 如何同时展示 Mermaid 图和源码

如果你只是写一个 mermaid 代码块,那么在支持 Mermaid 的环境里,读者通常只能看到渲染结果,而看不到原始语法。

如果你写的是教程文章,最推荐的方式是把内容分成两部分:

  • 第一部分叫"渲染效果",用真正的 mermaid 代码块
  • 第二部分叫"对应语法",用 markdown 代码块原样展示 Mermaid 源码

这样读者既能看懂图,也能学会怎么写。

4.1 推荐写法

渲染效果

#mermaid-svg-UiLnOaMLPc4XuSN7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-UiLnOaMLPc4XuSN7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UiLnOaMLPc4XuSN7 .error-icon{fill:#552222;}#mermaid-svg-UiLnOaMLPc4XuSN7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UiLnOaMLPc4XuSN7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UiLnOaMLPc4XuSN7 .marker.cross{stroke:#333333;}#mermaid-svg-UiLnOaMLPc4XuSN7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UiLnOaMLPc4XuSN7 p{margin:0;}#mermaid-svg-UiLnOaMLPc4XuSN7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-UiLnOaMLPc4XuSN7 .cluster-label text{fill:#333;}#mermaid-svg-UiLnOaMLPc4XuSN7 .cluster-label span{color:#333;}#mermaid-svg-UiLnOaMLPc4XuSN7 .cluster-label span p{background-color:transparent;}#mermaid-svg-UiLnOaMLPc4XuSN7 .label text,#mermaid-svg-UiLnOaMLPc4XuSN7 span{fill:#333;color:#333;}#mermaid-svg-UiLnOaMLPc4XuSN7 .node rect,#mermaid-svg-UiLnOaMLPc4XuSN7 .node circle,#mermaid-svg-UiLnOaMLPc4XuSN7 .node ellipse,#mermaid-svg-UiLnOaMLPc4XuSN7 .node polygon,#mermaid-svg-UiLnOaMLPc4XuSN7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UiLnOaMLPc4XuSN7 .rough-node .label text,#mermaid-svg-UiLnOaMLPc4XuSN7 .node .label text,#mermaid-svg-UiLnOaMLPc4XuSN7 .image-shape .label,#mermaid-svg-UiLnOaMLPc4XuSN7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-UiLnOaMLPc4XuSN7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-UiLnOaMLPc4XuSN7 .rough-node .label,#mermaid-svg-UiLnOaMLPc4XuSN7 .node .label,#mermaid-svg-UiLnOaMLPc4XuSN7 .image-shape .label,#mermaid-svg-UiLnOaMLPc4XuSN7 .icon-shape .label{text-align:center;}#mermaid-svg-UiLnOaMLPc4XuSN7 .node.clickable{cursor:pointer;}#mermaid-svg-UiLnOaMLPc4XuSN7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-UiLnOaMLPc4XuSN7 .arrowheadPath{fill:#333333;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UiLnOaMLPc4XuSN7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UiLnOaMLPc4XuSN7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-UiLnOaMLPc4XuSN7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UiLnOaMLPc4XuSN7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-UiLnOaMLPc4XuSN7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UiLnOaMLPc4XuSN7 .cluster text{fill:#333;}#mermaid-svg-UiLnOaMLPc4XuSN7 .cluster span{color:#333;}#mermaid-svg-UiLnOaMLPc4XuSN7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-UiLnOaMLPc4XuSN7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-UiLnOaMLPc4XuSN7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-UiLnOaMLPc4XuSN7 .icon-shape,#mermaid-svg-UiLnOaMLPc4XuSN7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UiLnOaMLPc4XuSN7 .icon-shape p,#mermaid-svg-UiLnOaMLPc4XuSN7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-UiLnOaMLPc4XuSN7 .icon-shape .label rect,#mermaid-svg-UiLnOaMLPc4XuSN7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UiLnOaMLPc4XuSN7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-UiLnOaMLPc4XuSN7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-UiLnOaMLPc4XuSN7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 前端
网关
服务A
服务B

对应语法
markdown 复制代码
```mermaid
flowchart LR
    A[前端] --> B[网关]
    B --> C[服务A]
    B --> D[服务B]
```

4.2 为什么外层用了四个反引号

因为你要在 Markdown 里展示一段"带三个反引号的代码块",所以外层必须用更多反引号把它包起来。

否则 Markdown 会误以为内部的三个反引号已经结束了代码块。

这个技巧很实用,写教程时经常会用到。

5. Mermaid 常见用法

下面用"效果 + 语法 + 说明"的方式,分别看几个最常见的 Mermaid 图。

5.1 流程图

流程图是 Mermaid 最常见的用途之一,适合描述业务步骤、程序流程、审批逻辑等。

渲染效果

#mermaid-svg-FtXQogeVvSDqqqaF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FtXQogeVvSDqqqaF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FtXQogeVvSDqqqaF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FtXQogeVvSDqqqaF .error-icon{fill:#552222;}#mermaid-svg-FtXQogeVvSDqqqaF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FtXQogeVvSDqqqaF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FtXQogeVvSDqqqaF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FtXQogeVvSDqqqaF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FtXQogeVvSDqqqaF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FtXQogeVvSDqqqaF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FtXQogeVvSDqqqaF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FtXQogeVvSDqqqaF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FtXQogeVvSDqqqaF .marker.cross{stroke:#333333;}#mermaid-svg-FtXQogeVvSDqqqaF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FtXQogeVvSDqqqaF p{margin:0;}#mermaid-svg-FtXQogeVvSDqqqaF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FtXQogeVvSDqqqaF .cluster-label text{fill:#333;}#mermaid-svg-FtXQogeVvSDqqqaF .cluster-label span{color:#333;}#mermaid-svg-FtXQogeVvSDqqqaF .cluster-label span p{background-color:transparent;}#mermaid-svg-FtXQogeVvSDqqqaF .label text,#mermaid-svg-FtXQogeVvSDqqqaF span{fill:#333;color:#333;}#mermaid-svg-FtXQogeVvSDqqqaF .node rect,#mermaid-svg-FtXQogeVvSDqqqaF .node circle,#mermaid-svg-FtXQogeVvSDqqqaF .node ellipse,#mermaid-svg-FtXQogeVvSDqqqaF .node polygon,#mermaid-svg-FtXQogeVvSDqqqaF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FtXQogeVvSDqqqaF .rough-node .label text,#mermaid-svg-FtXQogeVvSDqqqaF .node .label text,#mermaid-svg-FtXQogeVvSDqqqaF .image-shape .label,#mermaid-svg-FtXQogeVvSDqqqaF .icon-shape .label{text-anchor:middle;}#mermaid-svg-FtXQogeVvSDqqqaF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FtXQogeVvSDqqqaF .rough-node .label,#mermaid-svg-FtXQogeVvSDqqqaF .node .label,#mermaid-svg-FtXQogeVvSDqqqaF .image-shape .label,#mermaid-svg-FtXQogeVvSDqqqaF .icon-shape .label{text-align:center;}#mermaid-svg-FtXQogeVvSDqqqaF .node.clickable{cursor:pointer;}#mermaid-svg-FtXQogeVvSDqqqaF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FtXQogeVvSDqqqaF .arrowheadPath{fill:#333333;}#mermaid-svg-FtXQogeVvSDqqqaF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FtXQogeVvSDqqqaF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FtXQogeVvSDqqqaF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FtXQogeVvSDqqqaF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FtXQogeVvSDqqqaF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FtXQogeVvSDqqqaF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FtXQogeVvSDqqqaF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FtXQogeVvSDqqqaF .cluster text{fill:#333;}#mermaid-svg-FtXQogeVvSDqqqaF .cluster span{color:#333;}#mermaid-svg-FtXQogeVvSDqqqaF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FtXQogeVvSDqqqaF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FtXQogeVvSDqqqaF rect.text{fill:none;stroke-width:0;}#mermaid-svg-FtXQogeVvSDqqqaF .icon-shape,#mermaid-svg-FtXQogeVvSDqqqaF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FtXQogeVvSDqqqaF .icon-shape p,#mermaid-svg-FtXQogeVvSDqqqaF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FtXQogeVvSDqqqaF .icon-shape .label rect,#mermaid-svg-FtXQogeVvSDqqqaF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FtXQogeVvSDqqqaF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FtXQogeVvSDqqqaF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FtXQogeVvSDqqqaF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

开始
读取配置
配置有效?
启动服务
输出错误并退出
结束

对应语法
markdown 复制代码
```mermaid
flowchart TD
    Start([开始]) --> Input[读取配置]
    Input --> Check{配置有效?}
    Check -->|是| Run[启动服务]
    Check -->|否| Error[输出错误并退出]
    Run --> End([结束])
    Error --> End
```
语法说明

常见方向:

  • TD:从上到下
  • LR:从左到右

常见节点写法:

  • A[矩形节点]
  • A(圆角节点)
  • A{判断节点}
  • A([开始/结束])

5.2 时序图

时序图很适合描述接口调用、认证流程、服务交互和消息传递链路。

渲染效果

Database Backend Frontend User Database Backend Frontend User #mermaid-svg-iJVER4wluIazkAhP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iJVER4wluIazkAhP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iJVER4wluIazkAhP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iJVER4wluIazkAhP .error-icon{fill:#552222;}#mermaid-svg-iJVER4wluIazkAhP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iJVER4wluIazkAhP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iJVER4wluIazkAhP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iJVER4wluIazkAhP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iJVER4wluIazkAhP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iJVER4wluIazkAhP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iJVER4wluIazkAhP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iJVER4wluIazkAhP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iJVER4wluIazkAhP .marker.cross{stroke:#333333;}#mermaid-svg-iJVER4wluIazkAhP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iJVER4wluIazkAhP p{margin:0;}#mermaid-svg-iJVER4wluIazkAhP .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-iJVER4wluIazkAhP text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-iJVER4wluIazkAhP .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-iJVER4wluIazkAhP .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-iJVER4wluIazkAhP .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-iJVER4wluIazkAhP #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-iJVER4wluIazkAhP .sequenceNumber{fill:white;}#mermaid-svg-iJVER4wluIazkAhP #sequencenumber{fill:#333;}#mermaid-svg-iJVER4wluIazkAhP #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-iJVER4wluIazkAhP .messageText{fill:#333;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-iJVER4wluIazkAhP .labelText,#mermaid-svg-iJVER4wluIazkAhP .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .loopText,#mermaid-svg-iJVER4wluIazkAhP .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-iJVER4wluIazkAhP .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-iJVER4wluIazkAhP .noteText,#mermaid-svg-iJVER4wluIazkAhP .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-iJVER4wluIazkAhP .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-iJVER4wluIazkAhP .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-iJVER4wluIazkAhP .actorPopupMenu{position:absolute;}#mermaid-svg-iJVER4wluIazkAhP .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-iJVER4wluIazkAhP .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-iJVER4wluIazkAhP .actor-man circle,#mermaid-svg-iJVER4wluIazkAhP line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-iJVER4wluIazkAhP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 提交登录表单发送登录请求查询用户信息返回用户记录返回 Token登录成功

对应语法
markdown 复制代码
```mermaid
sequenceDiagram
    participant U as User
    participant F as Frontend
    participant B as Backend
    participant D as Database

    U->>F: 提交登录表单
    F->>B: 发送登录请求
    B->>D: 查询用户信息
    D-->>B: 返回用户记录
    B-->>F: 返回 Token
    F-->>U: 登录成功
```
语法说明
  • sequenceDiagram 表示时序图
  • participant 用来声明参与者
  • as 可以给参与者设置显示名称
  • ->> 表示发送消息
  • -->> 常用于返回结果

5.3 类图

Mermaid 也支持类图,适合做轻量级结构说明。

渲染效果

#mermaid-svg-Y0q3TApC3G5VOGjI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Y0q3TApC3G5VOGjI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Y0q3TApC3G5VOGjI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Y0q3TApC3G5VOGjI .error-icon{fill:#552222;}#mermaid-svg-Y0q3TApC3G5VOGjI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Y0q3TApC3G5VOGjI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Y0q3TApC3G5VOGjI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Y0q3TApC3G5VOGjI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Y0q3TApC3G5VOGjI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Y0q3TApC3G5VOGjI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Y0q3TApC3G5VOGjI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Y0q3TApC3G5VOGjI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Y0q3TApC3G5VOGjI .marker.cross{stroke:#333333;}#mermaid-svg-Y0q3TApC3G5VOGjI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Y0q3TApC3G5VOGjI p{margin:0;}#mermaid-svg-Y0q3TApC3G5VOGjI g.classGroup text{fill:#9370DB;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-Y0q3TApC3G5VOGjI g.classGroup text .title{font-weight:bolder;}#mermaid-svg-Y0q3TApC3G5VOGjI .cluster-label text{fill:#333;}#mermaid-svg-Y0q3TApC3G5VOGjI .cluster-label span{color:#333;}#mermaid-svg-Y0q3TApC3G5VOGjI .cluster-label span p{background-color:transparent;}#mermaid-svg-Y0q3TApC3G5VOGjI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Y0q3TApC3G5VOGjI .cluster text{fill:#333;}#mermaid-svg-Y0q3TApC3G5VOGjI .cluster span{color:#333;}#mermaid-svg-Y0q3TApC3G5VOGjI .nodeLabel,#mermaid-svg-Y0q3TApC3G5VOGjI .edgeLabel{color:#131300;}#mermaid-svg-Y0q3TApC3G5VOGjI .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-Y0q3TApC3G5VOGjI .label text{fill:#131300;}#mermaid-svg-Y0q3TApC3G5VOGjI .labelBkg{background:#ECECFF;}#mermaid-svg-Y0q3TApC3G5VOGjI .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-Y0q3TApC3G5VOGjI .classTitle{font-weight:bolder;}#mermaid-svg-Y0q3TApC3G5VOGjI .node rect,#mermaid-svg-Y0q3TApC3G5VOGjI .node circle,#mermaid-svg-Y0q3TApC3G5VOGjI .node ellipse,#mermaid-svg-Y0q3TApC3G5VOGjI .node polygon,#mermaid-svg-Y0q3TApC3G5VOGjI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Y0q3TApC3G5VOGjI .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI g.clickable{cursor:pointer;}#mermaid-svg-Y0q3TApC3G5VOGjI g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-Y0q3TApC3G5VOGjI g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-Y0q3TApC3G5VOGjI .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-Y0q3TApC3G5VOGjI .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-Y0q3TApC3G5VOGjI .dashed-line{stroke-dasharray:3;}#mermaid-svg-Y0q3TApC3G5VOGjI .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-Y0q3TApC3G5VOGjI #compositionStart,#mermaid-svg-Y0q3TApC3G5VOGjI .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI #compositionEnd,#mermaid-svg-Y0q3TApC3G5VOGjI .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI #dependencyStart,#mermaid-svg-Y0q3TApC3G5VOGjI .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI #dependencyStart,#mermaid-svg-Y0q3TApC3G5VOGjI .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI #extensionStart,#mermaid-svg-Y0q3TApC3G5VOGjI .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI #extensionEnd,#mermaid-svg-Y0q3TApC3G5VOGjI .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI #aggregationStart,#mermaid-svg-Y0q3TApC3G5VOGjI .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI #aggregationEnd,#mermaid-svg-Y0q3TApC3G5VOGjI .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI #lollipopStart,#mermaid-svg-Y0q3TApC3G5VOGjI .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI #lollipopEnd,#mermaid-svg-Y0q3TApC3G5VOGjI .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Y0q3TApC3G5VOGjI .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-Y0q3TApC3G5VOGjI .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Y0q3TApC3G5VOGjI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Y0q3TApC3G5VOGjI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Y0q3TApC3G5VOGjI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} User
+String name
+login()
+logout()
Admin
+manageUser()

对应语法
markdown 复制代码
```mermaid
classDiagram
    class User {
        +String name
        +login()
        +logout()
    }

    class Admin {
        +manageUser()
    }

    User <|-- Admin
```
语法说明
  • classDiagram 表示类图
  • class User { ... } 用来定义类
  • + 常表示公开成员
  • <|-- 表示继承关系

如果类图只是简单展示结构,Mermaid 足够好用;但如果要表达更完整的 UML 关系,PlantUML 通常更强。

6. PlantUML 是什么

PlantUML 同样是一种"用文本生成图表"的工具,但它更偏向 UML 建模和工程化表达。

它的特点是:

  • UML 图支持更完整
  • 类图、用例图、组件图、部署图更强
  • 更适合架构设计、系统分析、正式设计文档
  • 语法能力更丰富,但学习成本也略高一些

先看一个最小示例。

plantuml 复制代码
@startuml
Alice -> Bob: Hello
Bob --> Alice: Hi
@enduml

这会生成一个简单的时序图。

7. PlantUML 常见用法

7.1 基本结构

PlantUML 最常见的写法,是以 @startuml 开始,以 @enduml 结束。

plantuml 复制代码
@startuml
actor User
participant Frontend
participant Backend

User -> Frontend: 登录
Frontend -> Backend: 验证账号密码
Backend --> Frontend: 返回结果
Frontend --> User: 展示登录结果
@enduml

这一对标记可以理解为:告诉 PlantUML,"下面这段内容是一张图的定义"。

7.2 类图

PlantUML 在类图方面非常强大,表达能力明显强于 Mermaid。

plantuml 复制代码
@startuml
class User {
  -id: Long
  -name: String
  +login()
  +logout()
}

class Order {
  -orderId: String
  -amount: Decimal
  +create()
  +cancel()
}

User "1" --> "*" Order : owns
@enduml

你可以清晰表达:

  • 属性与方法
  • 访问修饰符
  • 继承、实现、关联、聚合、组合
  • 多重性关系

7.3 用例图

plantuml 复制代码
@startuml
left to right direction
actor User
actor Admin

rectangle System {
  usecase "登录" as UC1
  usecase "查看订单" as UC2
  usecase "管理用户" as UC3
}

User --> UC1
User --> UC2
Admin --> UC1
Admin --> UC3
@enduml

这种图很适合需求分析和系统建模阶段使用。

7.4 组件图

plantuml 复制代码
@startuml
package "Web Layer" {
  [Frontend]
  [API Gateway]
}

package "Service Layer" {
  [User Service]
  [Order Service]
}

database "MySQL" as DB

[Frontend] --> [API Gateway]
[API Gateway] --> [User Service]
[API Gateway] --> [Order Service]
[User Service] --> DB
[Order Service] --> DB
@enduml

如果你要写系统架构说明、模块划分或服务依赖关系,这类图很有帮助。

8. Mermaid 和 PlantUML 怎么选

如果只用一句话概括:

  • 想快速写文档、写流程说明、写 README,用 Mermaid
  • 想严谨表达 UML、建模系统结构,用 PlantUML

更具体一点:

8.1 Mermaid 更适合

  • Markdown 文档
  • 轻量流程图
  • 时序图
  • 项目 README
  • 前后端开发说明
  • 团队知识库

8.2 PlantUML 更适合

  • UML 建模
  • 类图、组件图、部署图
  • 架构设计文档
  • 复杂系统关系表达
  • 正式的分析与设计资料

可以简单理解为:

  • Mermaid 偏"轻文档化"
  • PlantUML 偏"强建模化"

9. 两者对比

对比项 Mermaid PlantUML
上手难度
文档集成 很强 较强
UML 支持完整度 一般 很强
流程图体验 很好 不错
类图能力 基础够用 非常强
架构建模能力 中等 很强
适合场景 Markdown/文档说明 设计文档/架构建模

如果你的目标是"快速把图写进文档",Mermaid 往往更省事。

如果你的目标是"把系统结构表达得更完整、更专业",PlantUML 往往更合适。

10. 实际使用建议

在真实项目里,我比较推荐下面这种分工方式:

  • README、接口文档、流程说明:优先用 Mermaid
  • 领域模型、模块设计、部署结构:优先用 PlantUML
  • 文档平台已经支持 Mermaid 时,尽量就近使用
  • 需要长期沉淀设计资产时,优先考虑 PlantUML

一个很好记的经验是:

"用 Mermaid 管文档里的图,用 PlantUML 管设计里的图。"

11. 常见问题

11.1 Mermaid 和 PlantUML 能放进 Git 吗?

当然可以。它们本质上就是文本文件,非常适合版本管理。

11.2 它们能导出图片吗?

可以。常见方式包括:

  • 编辑器插件导出
  • 本地命令行工具导出
  • 在线渲染工具导出
  • 文档站点构建时自动渲染

11.3 哪个更适合新手?

Mermaid 更适合新手,因为语法更简单,和 Markdown 结合也更自然。

11.4 哪个更适合架构师或正式设计文档?

PlantUML 更适合,因为它对 UML 的支持更全面。

11.5 为什么我的 Mermaid 没有自动渲染?

最常见的原因不是语法写错,而是你当前使用的 Markdown 预览器本身不支持 Mermaid。

要实现自动渲染,通常需要满足以下条件之一:

  • 编辑器原生支持 Mermaid
  • 安装了 Mermaid 预览插件
  • 文档平台已经启用了 Mermaid 渲染能力

如果你只是用普通的 Markdown 查看器直接打开文件,它通常只会把 Mermaid 当作普通代码块显示。

12. 结语

Mermaid 和 PlantUML 的核心价值,不是替代所有画图工具,而是让图表像代码一样可维护。

当你的项目开始重视文档质量、架构清晰度和团队协作效率时,这类工具的价值会越来越明显。Mermaid 适合快速表达,PlantUML 适合严谨建模。掌握它们之后,你会发现很多原来需要截图、拖拽、反复修改的图,现在几行文本就能完成。

如果你经常写技术文档,建议先掌握 Mermaid;如果你还需要输出更正式的系统设计资料,再进一步学习 PlantUML。

附:文中示例汇总

Mermaid 流程图效果

#mermaid-svg-TafhnQtCqDFa0ijP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TafhnQtCqDFa0ijP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TafhnQtCqDFa0ijP .error-icon{fill:#552222;}#mermaid-svg-TafhnQtCqDFa0ijP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TafhnQtCqDFa0ijP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TafhnQtCqDFa0ijP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TafhnQtCqDFa0ijP .marker.cross{stroke:#333333;}#mermaid-svg-TafhnQtCqDFa0ijP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TafhnQtCqDFa0ijP p{margin:0;}#mermaid-svg-TafhnQtCqDFa0ijP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster-label text{fill:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster-label span{color:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster-label span p{background-color:transparent;}#mermaid-svg-TafhnQtCqDFa0ijP .label text,#mermaid-svg-TafhnQtCqDFa0ijP span{fill:#333;color:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .node rect,#mermaid-svg-TafhnQtCqDFa0ijP .node circle,#mermaid-svg-TafhnQtCqDFa0ijP .node ellipse,#mermaid-svg-TafhnQtCqDFa0ijP .node polygon,#mermaid-svg-TafhnQtCqDFa0ijP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TafhnQtCqDFa0ijP .rough-node .label text,#mermaid-svg-TafhnQtCqDFa0ijP .node .label text,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape .label,#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape .label{text-anchor:middle;}#mermaid-svg-TafhnQtCqDFa0ijP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TafhnQtCqDFa0ijP .rough-node .label,#mermaid-svg-TafhnQtCqDFa0ijP .node .label,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape .label,#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape .label{text-align:center;}#mermaid-svg-TafhnQtCqDFa0ijP .node.clickable{cursor:pointer;}#mermaid-svg-TafhnQtCqDFa0ijP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TafhnQtCqDFa0ijP .arrowheadPath{fill:#333333;}#mermaid-svg-TafhnQtCqDFa0ijP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TafhnQtCqDFa0ijP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TafhnQtCqDFa0ijP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TafhnQtCqDFa0ijP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TafhnQtCqDFa0ijP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TafhnQtCqDFa0ijP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TafhnQtCqDFa0ijP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster text{fill:#333;}#mermaid-svg-TafhnQtCqDFa0ijP .cluster span{color:#333;}#mermaid-svg-TafhnQtCqDFa0ijP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TafhnQtCqDFa0ijP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TafhnQtCqDFa0ijP rect.text{fill:none;stroke-width:0;}#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape p,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TafhnQtCqDFa0ijP .icon-shape .label rect,#mermaid-svg-TafhnQtCqDFa0ijP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TafhnQtCqDFa0ijP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TafhnQtCqDFa0ijP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TafhnQtCqDFa0ijP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

用户登录
认证成功?
进入首页
提示错误信息

Mermaid 流程图语法

markdown 复制代码
```mermaid
flowchart TD
    A[用户登录] --> B{认证成功?}
    B -->|是| C[进入首页]
    B -->|否| D[提示错误信息]
    D --> A
```

Mermaid 时序图效果

Database Backend Frontend User Database Backend Frontend User #mermaid-svg-iJVER4wluIazkAhP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iJVER4wluIazkAhP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iJVER4wluIazkAhP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iJVER4wluIazkAhP .error-icon{fill:#552222;}#mermaid-svg-iJVER4wluIazkAhP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iJVER4wluIazkAhP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iJVER4wluIazkAhP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iJVER4wluIazkAhP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iJVER4wluIazkAhP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iJVER4wluIazkAhP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iJVER4wluIazkAhP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iJVER4wluIazkAhP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iJVER4wluIazkAhP .marker.cross{stroke:#333333;}#mermaid-svg-iJVER4wluIazkAhP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iJVER4wluIazkAhP p{margin:0;}#mermaid-svg-iJVER4wluIazkAhP .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-iJVER4wluIazkAhP text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-iJVER4wluIazkAhP .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-iJVER4wluIazkAhP .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-iJVER4wluIazkAhP .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-iJVER4wluIazkAhP #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-iJVER4wluIazkAhP .sequenceNumber{fill:white;}#mermaid-svg-iJVER4wluIazkAhP #sequencenumber{fill:#333;}#mermaid-svg-iJVER4wluIazkAhP #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-iJVER4wluIazkAhP .messageText{fill:#333;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-iJVER4wluIazkAhP .labelText,#mermaid-svg-iJVER4wluIazkAhP .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .loopText,#mermaid-svg-iJVER4wluIazkAhP .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-iJVER4wluIazkAhP .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-iJVER4wluIazkAhP .noteText,#mermaid-svg-iJVER4wluIazkAhP .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-iJVER4wluIazkAhP .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-iJVER4wluIazkAhP .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-iJVER4wluIazkAhP .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-iJVER4wluIazkAhP .actorPopupMenu{position:absolute;}#mermaid-svg-iJVER4wluIazkAhP .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-iJVER4wluIazkAhP .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-iJVER4wluIazkAhP .actor-man circle,#mermaid-svg-iJVER4wluIazkAhP line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-iJVER4wluIazkAhP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 提交登录表单发送登录请求查询用户信息返回用户记录返回 Token登录成功

Mermaid 时序图语法

markdown 复制代码
```mermaid
sequenceDiagram
    participant U as User
    participant F as Frontend
    participant B as Backend
    participant D as Database

    U->>F: 提交登录表单
    F->>B: 发送登录请求
    B->>D: 查询用户信息
    D-->>B: 返回用户记录
    B-->>F: 返回 Token
    F-->>U: 登录成功
```

PlantUML 类图

plantuml 复制代码
@startuml
class User {
  -id: Long
  -name: String
  +login()
  +logout()
}

class Order {
  -orderId: String
  -amount: Decimal
  +create()
  +cancel()
}

User "1" --> "*" Order : owns
@enduml

PlantUML 组件图

plantuml 复制代码
@startuml
package "Web Layer" {
  [Frontend]
  [API Gateway]
}

package "Service Layer" {
  [User Service]
  [Order Service]
}

database "MySQL" as DB

[Frontend] --> [API Gateway]
[API Gateway] --> [User Service]
[API Gateway] --> [Order Service]
[User Service] --> DB
[Order Service] --> DB
@enduml