Mermaid State Diagram 教程:状态机、状态转换与正交状态

puml.online

Mermaid 的 State Diagram(状态图)让你用文本描述状态机——比画 Visio 快,比写代码更直观。适合:订单状态流转、用户生命周期、审批流程、协议状态机。

为什么选 State Diagram 而不是 Flowchart

Flowchart(流程图)描述的是过程——做什么、先做什么后做什么。State Diagram 描述的是状态——系统/实体在什么时候处于什么状态,以及在什么条件下从一个状态切换到另一个状态。

适用场景:

  • 订单系统:待支付 → 已支付 → 已发货 → 已收货 → 已完成(每个状态都是实体的快照)
  • 审批流:草稿 → 提交 → 审核中 → 审核通过/驳回
  • 网络协议:握手 → 连接中 → 传输 → 断开
  • 用户生命周期:注册 → 激活 → 活跃 → 沉睡 → 注销

Flowchart 画订单流程也可以,但状态图更精确地描述了”实体在某个时刻的状态”这个概念。

一、最小例子

1
2
3
4
5
6
stateDiagram-v2
[*] --> 待支付
待支付 --> 已支付: 支付成功
已支付 --> 已发货: 商家发货
已发货 --> 已收货: 确认收货
已收货 --> [*]
  • [*] 是特殊状态,表示开始或结束
  • stateDiagram-v2 是当前推荐语法(比 stateDiagram 更丰富)
  • --> 是状态转换箭头,后面可以跟 转换条件: 触发事件

二、两种语法:stateDiagram vs stateDiagram-v2

功能 stateDiagram stateDiagram-v2
基本状态 ✅ ✅
嵌套状态 ❌ ✅
正交状态(` `)
分支(choice) ❌ ✅
入口/出口动作 ❌ ✅

始终用 stateDiagram-v2。

三、状态声明三种方式

3.1 简短写法

1
state "状态显示名" as 状态ID

3.2 完整写法(带 description)

1
state 状态ID: 这是描述\n第二行描述

3.3 匿名状态

直接写文字,Mermaid 自动生成 ID:

1
[*] --> 待支付

四、状态转换箭头

4.1 基本箭头

1
2
3
4
5
6
7
8
stateDiagram-v2
[*] --> 草稿
草稿 --> 提交: submit
提交 --> 审核中: review
审核中 --> 通过: approve
审核中 --> 驳回: reject
通过 --> [*]
驳回 --> 草稿: revise

4.2 带条件和事件的箭头

1
状态A --> 状态B: 事件[条件]
1
2
3
4
5
stateDiagram-v2
[*] --> 活跃
活跃 --> 沉睡: inactive[>30天]
沉睡 --> 活跃: login
沉睡 --> 注销: expire[>180天]

inactive[>30天] 是条件,login 是触发事件。

4.3 分支(choice)

1
2
3
4
5
6
7
stateDiagram-v2
[*] --> 支付
支付 --> 判定: 回调
判定 --> 成功: amount > 0
判定 --> 失败: amount <= 0
成功 --> [*]
失败 --> [*]

用 --> 和条件做 if/else 分支。

五、嵌套状态(Composite State)

stateDiagram-v2 支持状态嵌套,用于表达”这个状态内部还有子状态”:

1
2
3
4
5
6
7
8
9
10
11
stateDiagram-v2
[*] --> 登录中
登录中 --> 已登录: 验证成功
已登录 --> 登出: logout

state 登录中 {
[*] --> 输入密码
输入密码 --> 验证中: submit
验证中 --> 输入密码: 重试
验证中 --> 已登录: 验证成功
}

嵌套状态让图更清晰——“登录中”是一个复合状态,里面有自己的子状态流转。

嵌套层数限制

Mermaid 支持最多 3 层嵌套,超过会渲染异常。

六、正交状态(Concurrent States)

正交状态用 || 表示”同时存在的多个独立状态”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
stateDiagram-v2
[*] --> 任务进行中

state "任务进行中" as Task {
[*] --> 开发
开发 --> 测试: dev done
测试 --> 上线: test passed

--

[*] --> 文档编写
文档编写 --> 文档完成: doc done
}

任务进行中 --> [*]: 全部完成

-- 分隔符在同一父状态内创建并行区域。开发和文档编写是同时进行的两个独立子流程。

七、入口动作和出口动作

1
2
3
4
5
6
7
8
9
10
11
12
13
stateDiagram-v2
[*] --> 初始化
初始化 --> 就绪: init complete

state 就绪 {
[*] --> 空闲
空闲 --> 处理中: job received
处理中 --> 空闲: job complete

空闲 : entry/ log('进入空闲')
处理中 : entry/ log('开始处理')
处理中 : exit/ log('退出处理')
}

entry/ 和 exit/ 在状态名称后声明,进入/退出该状态时触发动作。

八、样式和主题

8.1 单状态染色

1
2
3
4
5
6
7
8
stateDiagram-v2
[*] --> 待处理
待处理 --> 处理中
处理中 --> 已完成

style 待处理 fill:#f9f,stroke:#333
style 处理中 fill:#ff6b6b,stroke:#333
style 已完成 fill:#6bcb77,stroke:#333

8.2 样式类(多个状态复用)

1
2
3
4
5
6
7
stateDiagram-v2
[*] --> A
A --> B
B --> [*]

classDef errorState fill:#ff6b6b,stroke:#333
class B errorState

8.3 切换主题

1
2
3
4
5
%%{init: {'theme': 'dark'}}%%
stateDiagram-v2
[*] --> 活跃
活跃 --> 休眠: sleep
休眠 --> 活跃: wake

九、和 PlantUML State Diagram 的对比

功能 Mermaid stateDiagram-v2 PlantUML State Diagram
嵌套状态 ✅ 最多 3 层 ✅ 支持多层
正交状态 ✅ ✅
入口/出口动作 ✅ ✅
分支(choice) ✅ ✅
图类型 手绘风格 UML 严谨风格
中文支持 ✅ ✅
代码可读性 高(文本紧凑) 中

两者功能几乎等价,选择取决于你更看重可读性(选 Mermaid)还是UML 规范性(选 PlantUML)。

十、常见报错

报错 原因 修复
Parse error 状态 ID 含空格或特殊字符 用引号 "Long ID"
Invalid transition 转换目标状态不存在 检查状态 ID 拼写
Too many nested levels 嵌套超过 3 层 减少嵌套或拆成多个子图
Circular dependency 循环箭头没有终止条件 加 [*] 终态

小结

Mermaid State Diagram 记住 5 点:

  1. 始终用 stateDiagram-v2(旧版 stateDiagram 功能残缺)
  2. [*] 是开始/结束状态
  3. --> 目标: 事件[条件] 是带条件的状态转换
  4. 嵌套状态用 state 父 { 子状态 } 表达复合状态
  5. || 分隔并行子区域,表达同时进行的独立状态流

状态图适合描述实体在生命周期内的状态变化——订单、审批、用户、设备、会话,都适合用 State Diagram 画。

  • 标题: Mermaid State Diagram 教程:状态机、状态转换与正交状态
  • 作者: puml.online
  • 创建于 : 2026-08-08 10:00:00
  • 更新于 : 2026-09-29 01:06:38
  • 链接: https://puml.online/blog/mermaid-state-diagram/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。