状态驱动的前端页面设计:让按钮、标签和流程保持一致

759 字
4 分钟
状态驱动的前端页面设计:让按钮、标签和流程保持一致
订单和异常模块有一个共同特点:同一条数据在不同状态下,颜色、文案、按钮和下一步都不同。若把规则散在几十个 v-if 中,页面迟早会出现“显示待调度,却还能再次审核”的矛盾。
1. 原始状态与展示状态分开
服务端状态是业务事实,页面标签是面向用户的分组。小程序把多个后台终态归入“已完成”标签,但卡片仍显示“已取消”“已驳回”等具体状态。
const historyStates = new Set([ 'COMPLETED', 'CANCELED', 'REJECTED', 'DELIVERY_FAILED'])分组用于筛选,原始状态用于解释,二者不能互相覆盖。
2. 状态元数据表
const ORDER_STATUS_META = { UNPAID: { label: '待支付', tone: 'danger' }, PENDING_AUDIT: { label: '待审核', tone: 'warning' }, WAIT_DISPATCH: { label: '待调度', tone: 'success' }, DELIVERING: { label: '配送中', tone: 'primary' }, COMPLETED: { label: '已完成', tone: 'info' }}列表、详情和消息卡片从同一份元数据读取文案与色彩。未知状态必须有安全回退,而不是渲染空白。
3. 操作白名单
按钮应从“当前状态允许什么”推导:
const ACTIONS_BY_STATUS = { PENDING_AUDIT: ['approve', 'reject'], WAIT_DISPATCH: ['cancel', 'startFlight'], DELIVERING: ['markDelivered', 'markFailed']}
const can = action => (ACTIONS_BY_STATUS[status.value] || []).includes(action)前端白名单改善体验,后端仍要再次校验状态,防止重复请求或越权调用。
4. 派生状态不要重复保存
“是否历史订单”“是否可以支付”“异常处于登记还是跟踪阶段”都可以由原始数据计算:
const stage = computed(() => ticket.value?.resultOrderId ? 'tracking' : 'registration')如果同时保存 stage 和 resultOrderId,其中一个更新失败就会产生矛盾。能计算出来的状态尽量用 computed。
5. 操作后重新获取事实
审核、支付、取消或完成配送后,不只修改本地 status,而是重新读取详情。一次后端动作可能同时生成流程日志、任务和通知,本地只改一个字段无法覆盖全部副作用。
6. 终态与中间态
终态通常只读,中间态允许继续操作。异常流程还存在派生订单,使“原订单终态”不等于“异常处理结束”。状态设计要围绕业务对象分别判断,不能拿订单状态替代工单状态。
7. 状态文案也属于规则
同一个值在用户端与管理端可以有不同表达,例如后台“待审核”对用户可解释为“订单已提交,等待平台确认”。枚举值保持一致,展示文案根据角色转换。
8. 本篇小结
状态驱动并不是把 if 换成对象,而是承认页面行为来自业务状态。规则集中以后,按钮不再各有各的想法,整个页面终于像同一个团队开发的——哪怕这个团队其实就是昨天和今天的我。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
状态驱动的前端页面设计:让按钮、标签和流程保持一致
https://firefly.cuteleaf.cn/posts/state-driven-frontend-ui/相关文章智能推荐
1
管理端开发日记④:三种异常处置流程的实现
前端开发深入拆解取消退款、重新派送和补发订单三条异常处置分支,以及原订单、子订单、日志和飞行任务之间的关系。
2
编辑表单的数据回显与提交:新增、修改和重提如何共用页面
前端开发总结订单与地址表单的字段归一化、异步回显、枚举转换、图片差异提交和状态清理。
3
小程序开发日记①:快递与外卖下单流程
前端开发记录快递、外卖两类订单从表单建模、收货地址、服务范围校验到凭证上传和提交的完整链路。
4
管理端开发日记①:订单列表与状态筛选
前端开发从查询参数、状态枚举、表格列到操作入口,完整记录无人机配送管理端订单列表的实现。
5
管理端开发日记②:订单详情、流程与数据回显
前端开发记录订单详情页如何并行加载基础信息、图片凭证、流程日志、历史版本和飞行任务,并依据状态组织操作区。
随机文章随机推荐





























