跳转到内容

状态机和反应

表单看起来完成了,但点击提交后呢:等待、输入错误、失败后保留内容,还是允许再次请求?可点击原型通常只展示其中一条路径。DFC Bridge 反应契约描述所有重要分支,包括反馈、焦点、历史和恢复。

  • 反应是 event + current state + guard → effects + next state,即事件与当前状态满足条件后,产生效果并进入下一状态。
  • 状态是组件、表单、流程或页面的稳定条件。
  • 视图([view=...])是页面或数据状态样例,如 default、loading、empty 或 error。
  • 目标是反应引用的稳定元素、状态、模态窗口、表单、路由或服务操作。

名为“成功”的截图不是完整的成功反应。还需描述提交中状态、响应处理、焦点去向、播报、再次执行以及导航和历史结果。

现有标签用于定位交互元素:

email [field=email] [name=email]
send [action=submit:lead-form]
lead-form [state=lead-form-idle]
success [state=lead-form-success]

原型连线可以提供补充证据。不要为每个事件、条件、超时、焦点目标、播报和 HTTP 状态都添加图层标签。把这些关系放进引用稳定标识的结构化 DFC Bridge 元数据。

每条反应应回答所有适用的字段:

字段 含义
id 稳定的反应标识。
scope 组件、表单、页面、应用或跨路由流程。
from / event 当前状态和触发的用户或系统事件。
guard 允许或拒绝转换的条件。
effects 验证、请求、存储、分析、剪贴板等副作用。
to 成功后的状态,同时定义失败、取消和超时分支。
feedback 可见状态及面向辅助技术的播报。
focus 焦点去向和恢复规则。
history URL、查询参数、片段、导航、replace/push 及后退前进结果。
concurrency 重复输入、取消、过期响应和处理顺序。
persistence 刷新、路由改变、关闭或更换设备后保留什么。

非独立模块片段。 此例只展示 bridge.interaction,省略了必需的外层字段。交换数据或验证完整契约前,将其放入交付契约规定的完整 bridge 结构。

{
"bridge": {
"interaction": {
"stateMachines": [{
"id": "lead-form",
"initial": "idle",
"states": ["idle", "invalid", "submitting", "success", "failure"],
"transitions": [{
"id": "submit-lead",
"from": ["idle", "invalid", "failure"],
"event": { "type": "submit", "source": "lead-form" },
"guard": "all-required-fields-valid",
"pending": { "to": "submitting", "duplicateEvent": "ignore", "cancel": "on-route-leave" },
"outcomes": {
"success": { "to": "success", "focus": "success-heading", "announce": "Lead sent" },
"validation": { "to": "invalid", "focus": "first-invalid-field", "announce": "Form has errors" },
"failure": { "to": "failure", "focus": "error-summary", "retry": "preserve-values" }
},
"history": "none"
}]
}]
}
}
}

按流程阅读此例:从允许的状态提交,检查条件,显示 submitting,再按响应进入分支。失败后保留值以便重试;成功后把焦点移到结果标题。这里的标识供适配器使用,不是要求把它们都塞进 Figma 图层名称。

范围 示例 依据
元素 获得焦点、按下、选中、无效 原生语义或 UI Kit 组件
组件 折叠面板展开、对话框忙碌、日期选择器月份 UI Kit 状态模型与实例内容
表单 未修改、已修改、验证中、提交中、成功 表单反应状态机
页面 / 数据 加载、空、部分结果、错误 根节点 [view] 样例与数据契约
应用 已退出登录、离线、权限改变 跨页面流程契约

不要为每个悬停状态建立页面根节点,也不要把整页错误藏在按钮变体中。父子状态机可以交互,但必须明确谁负责、事件如何传播。

记录 activate、submit、change、dismiss、select、drag、timeout、response 等语义事件,而不只是某种设备手势。再定义支持的输入:

  • 鼠标点击或触摸激活也应支持原生键盘操作;
  • 悬停出现的内容也要能通过键盘焦点显示并关闭;
  • 拖动要有单指针、键盘或控件替代方式;
  • 长按、滑动和多点手势要有可发现的替代方式;
  • 等待期间重复激活应遵守明确的并发规则。

遵循 WAI-ARIA Authoring Practices Guide 的交互和键盘约定,并优先采用可用的原生 HTML 语义。

每个字段定义:

  • 数据名、值类型、必填或选填,以及适用的自动填充用途;
  • 持续可见的标签、说明、接受格式和限制;
  • 未修改、聚焦、已填写、无效、禁用和只读时的呈现;
  • 验证时机:输入、失焦、换步或提交;
  • 规范错误代码或消息,以及与字段的关系;
  • 不会悄悄改变含义的规范化处理;
  • 依赖字段、条件显示和隐藏值的处理。

整个表单定义:

  • 客户端与服务器的验证职责;
  • 错误摘要、首个错误字段的焦点和播报;
  • 等待界面及仍可执行的操作;
  • 出错、登录过期、切换路由和重试时的值保留;
  • 成功结果、重复提交处理和幂等要求;
  • 重置或撤销确认,以及未保存内容的丢失处理。

占位文字不是标签。禁用控件不能自行解释原因,应在附近提供状态或说明。只读和禁用是不同的产品状态。

每条请求路径按需要覆盖 idle → pending → success | empty | partial | failure | cancelled | timed-out,并说明:

  • 是否保留旧内容,以及是否标记为过期;
  • 进度如何显示,等待多久后更换提示,最短和最长等待规则;
  • 重试策略、退避、离线队列和手动重试;
  • 查询、路由、模态窗口或组件实例改变时是否取消;
  • 竞态处理:最新请求优先、按序应用、合并或拒绝;
  • 重复操作的去重和幂等;
  • 乐观更新、回滚、冲突处理和撤销期限;
  • 状态播报如何避免无意义重复。

加载图标不是完整的异步契约。迟到的响应不能覆盖较新的查询结果或意外移动焦点。

对话框、抽屉、菜单、弹出层和展开区应定义:

  • 打开事件与允许状态;
  • 初始焦点,或焦点留在触发元素上的原因;
  • 是否为模态;
  • Tab/Shift+Tab 范围及适用的方向键规则;
  • Escape、关闭按钮、外部点击,以及关闭会丢失内容时的处理;
  • 返回触发元素的焦点,或触发元素消失后的替代目标;
  • 嵌套浮层和路由改变时的行为;
  • 滚动锁定及原位置恢复。

视觉隐藏的内容不能意外保持可操作。仅因布局折叠的内容不能丢失必需状态。可参考相应 APG 模式实现,但不能用它替代上述产品决策。

完整反应应说明下列情况下焦点去哪里:

  • 验证失败;
  • 模态窗口打开或关闭;
  • 内容插入、删除、重排或筛选;
  • 一个步骤完成;
  • 获得焦点的条目消失;
  • 路由改变或历史恢复;
  • 操作失败、超时或撤销。

用户能在原处继续时,默认保留焦点。只有为了下一任务或重要反馈才移动它。不要因渲染副作用意外把焦点重置到文档开头。

说明状态能否分享、加入书签和恢复。对筛选、选项卡、分页、所选记录、抽屉和多步流程,决定:

  • 存于路径、查询参数、片段、内存还是持久存储;
  • 用 push 新增还是用 replace 替换历史记录;
  • 后退和前进的结果;
  • 直接打开和刷新时如何初始化;
  • 如何处理无效或过期状态;
  • 如何恢复滚动与焦点;
  • 关闭浮层是否撤回一条历史记录。

深层链接必须直接初始化同一产品状态,不要求重放此前的点击。URL 不得暴露秘密或敏感表单值。

交付前至少列出:

路径 必需证据
正常成功 起点、中间反馈、最终状态、焦点和历史结果
无效输入 字段与摘要反馈、修正路径
空结果 解释和恢复操作
权限或认证失败 保留工作,以及重新认证或申请访问的路径
网络或服务器失败 能否重试,以及不可重试时的行为
超时或离线 缓存状态、排队任务、重连行为
取消或关闭 副作用清理和焦点恢复
重复或快速输入 确定的并发结果
后退、前进或刷新 状态、焦点和滚动恢复

交付该流程前检查以下事项。这是反应契约评审,不是页面或应用自动获得 Ready 的证明:

  • 每个交互元素都有动作或真实导航目标;
  • 每个动作都能解析到目标和完整反应记录;
  • 每个可到达的状态,包括等待和失败,都有设计或继承的组件契约;
  • 字段有标签、约束、错误和保留值的规则;
  • 已决定异步竞态、重复事件、取消、重试和回滚行为;
  • 焦点、播报、URL、历史和滚动行为明确;
  • 键盘、指针、触摸和辅助技术用户能够完成同一任务。

放大后滚动查看细节。按 Esc 关闭。