Mermaid 状态图 #
状态图(State Diagram)用于展示对象在其生命周期内的状态转换过程,以及触发这些转换的事件。
基本语法 #
1. 基本结构 #
mermaid
stateDiagram-v2
[*] --> 状态1
状态1 --> 状态2
状态2 --> [*]
2. 初始状态和终止状态 #
使用[*]表示初始状态和终止状态:
mermaid
stateDiagram-v2
[*] --> 初始状态
初始状态 --> 运行状态
运行状态 --> 暂停状态
暂停状态 --> 运行状态
运行状态 --> [*]
暂停状态 --> [*]
状态转换 #
1. 简单转换 #
mermaid
stateDiagram-v2
[*] --> 关闭
关闭 --> 打开: 按电源按钮
打开 --> 关闭: 按电源按钮
2. 带条件的转换 #
可以在转换上添加条件:
mermaid
stateDiagram-v2
[*] --> 准备
准备 --> 运行: 开始
运行 --> 成功: 条件1满足
运行 --> 失败: 条件2满足
成功 --> [*]
失败 --> [*]
3. 事件和条件 #
可以在转换中同时指定事件和条件:
mermaid
stateDiagram-v2
[*] --> 就绪
就绪 --> 运行: 启动事件[条件]
运行 --> 暂停: 暂停事件
暂停 --> 运行: 继续事件
运行 --> 完成: 完成事件
暂停 --> 取消: 取消事件
完成 --> [*]
取消 --> [*]
复合状态 #
复合状态是包含其他状态的状态:
1. 简单复合状态 #
mermaid
stateDiagram-v2
[*] --> 未登录
未登录 --> 登录中: 输入凭证
登录中 --> 已登录: 验证成功
登录中 --> 未登录: 验证失败
state 已登录 {
[*] --> 首页
首页 --> 个人中心
个人中心 --> 设置
设置 --> 首页
}
已登录 --> 未登录: 退出登录
2. 正交状态 #
正交状态表示同时进行的多个状态机:
mermaid
stateDiagram-v2
[*] --> 运行
state 运行 {
[*] --> 状态1
状态1 --> 状态2
--
[*] --> 状态A
状态A --> 状态B
}
运行 --> [*]
选择和连接 #
1. 选择(Choice) #
选择表示根据条件选择不同的转换路径:
mermaid
stateDiagram-v2
[*] --> 开始
开始 --> 选择点: 处理
state 选择点 <<choice>>
选择点 --> 路径1: 条件1
选择点 --> 路径2: 条件2
选择点 --> 路径3: 条件3
路径1 --> 结束
路径2 --> 结束
路径3 --> 结束
结束 --> [*]
2. 连接(Junction) #
连接用于合并或分支转换路径:
mermaid
stateDiagram-v2
[*] --> 状态1
[*] --> 状态2
state 连接点 <<fork>>
状态1 --> 连接点
状态2 --> 连接点
连接点 --> 状态3
连接点 --> 状态4
state 合并点 <<join>>
状态3 --> 合并点
状态4 --> 合并点
合并点 --> [*]
历史状态 #
历史状态用于记住复合状态上次离开时的子状态:
1. 浅历史(Shallow History) #
只记住直接子状态:
mermaid
stateDiagram-v2
[*] --> 复合状态
state 复合状态 {
[*] --> 子状态1
子状态1 --> 子状态2
子状态2 --> 子状态3
state 历史 <<history>>
}
复合状态 --> 外部状态: 退出
外部状态 --> 复合状态: 重新进入
外部状态 --> 复合状态: 从历史继续
复合状态: 从历史继续 --> 历史
2. 深历史(Deep History) #
记住所有层级的子状态:
mermaid
stateDiagram-v2
[*] --> 复合状态
state 复合状态 {
[*] --> 子状态1
子状态1 --> 子状态2
state 子状态2 {
[*] --> 孙状态1
孙状态1 --> 孙状态2
}
state 历史 <<history>>
}
复合状态 --> 外部状态: 退出
外部状态 --> 历史: 从深历史继续
活动和动作 #
1. 进入和退出动作 #
可以在状态的进入和退出时执行动作:
mermaid
stateDiagram-v2
[*] --> 状态1: 初始转换
state 状态1 {
[*] --> 子状态1
entry / 进入状态1
exit / 退出状态1
子状态1 --> 子状态2: 转换1
子状态2 --> 子状态1: 转换2
}
状态1 --> 状态2: 转换3
state 状态2 {
entry / 进入状态2
exit / 退出状态2
}
状态2 --> [*]: 结束
2. 内部转换 #
内部转换不改变状态,但可以执行动作:
mermaid
stateDiagram-v2
[*] --> 运行
state 运行 {
entry / 开始运行
exit / 停止运行
[*] --> 子状态
子状态: 事件 / 执行动作
}
运行 --> [*]
高级功能 #
1. 注释 #
可以添加注释:
mermaid
stateDiagram-v2
[*] --> 状态1
状态1 --> 状态2
%% 这是一个注释
状态2 --> [*]
2. 状态样式 #
可以为状态添加自定义样式:
mermaid
stateDiagram-v2
[*] --> 就绪
就绪 --> 运行
运行 --> 完成
完成 --> [*]
stateDef 强调 fill:#f96,stroke:#333,stroke-width:2px;
运行 : 强调
3. 并行区域 #
并行区域使用--分隔:
mermaid
stateDiagram-v2
[*] --> 工作
state 工作 {
[*] --> 处理数据
处理数据 --> 分析结果
--
[*] --> 检查系统
检查系统 --> 生成报告
}
工作 --> [*]
最佳实践 #
- 清晰的状态命名:使用有意义的状态名称
- 明确的转换条件:在转换上添加清晰的事件和条件
- 适当使用复合状态:将相关状态组织为复合状态
- 合理使用历史状态:需要记住之前状态时使用历史状态
- 避免过度复杂:将复杂的状态图分解为多个子图
常见问题 #
问题:初始状态不显示 #
解决方案:确保使用[*]定义初始状态
问题:复合状态内部转换不正确 #
解决方案:确保复合状态内部有自己的初始状态[*]
问题:条件转换不生效 #
解决方案:确保条件格式正确,使用[条件]语法
完整示例 #
下面是一个完整的订单状态图示例:
mermaid
stateDiagram-v2
[*] --> 待付款
待付款 --> 已付款: 用户支付
待付款 --> 已取消: 用户取消
待付款 --> 已关闭: 超时未支付
已付款 --> 待发货: 系统确认
已付款 --> 退款中: 用户申请退款
state 待发货 {
[*] --> 配货中
配货中 --> 已出库: 仓库发货
已出库 --> 待收货
}
待发货 --> 部分发货: 部分商品缺货
待发货 --> 已取消: 商家取消
待收货 --> 已完成: 用户确认收货
待收货 --> 退款中: 用户申请退货
退款中 --> 已退款: 退款成功
退款中 --> 退款失败: 退款审核不通过
已完成 --> [*]
已取消 --> [*]
已关闭 --> [*]
已退款 --> [*]
退款失败 --> 待收货: 继续交易
最后更新:2026-02-08