ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

鸿蒙原生应用 ArkTS 严格模式:预约页的 @State 真单选与动态回显

鸿蒙原生应用 ArkTS 严格模式:预约页的 @State 真单选与动态回显 鸿蒙原生应用 ArkTS 严格模式预约页的 State 真单选与动态回显App 23「实验室设备预约」预约 TabFunc2Tab是预约时段选择页——State slot真单选4 时段 Flex 换行胶囊09:00-11:00 默认选中 确认预约按钮预约成功: 明天 09:00-11:00动态回显 预约记录列表4 条待使用橙/已完成绿。本篇基于23-lab-booking/entry/src/main/ets/pages/Func2Tab.ets约 126 行逐段拆解附 4 张实机截图。一、整体结构选时段 → 提交 → 看记录Func2Tab 是选时段 → 确认 → 看历史的预约流程build() { Column() { this.Header() Scroll() { Column({ space: 16 }) { this.SectionTitle(选择时段) this.SlotCard() this.SubmitBtn() this.SectionTitle(预约记录) this.BookingList() } .width(100%) .padding({ left: D.pad, right: D.pad, top: 16, bottom: D.pad this.safeBottom 20 }) } .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top) } .width(100%).height(100%).backgroundColor(C.bg) }5 个块按选 → 提交 → 看漏斗展开SectionTitle(选择时段)— 区块标题SlotCard— 4 时段 Flex 单选本页核心交互SubmitBtn— 确认预约动态回显时段SectionTitle(预约记录)— 区块标题BookingList— 4 条预约记录待使用橙/已完成绿与 App 14 场地预约的对比App 14 是场地选择 场次 Grid 三态App 23 是4 时段 Flex 单选——App 23 更简单4 个时段、单选、无三态——实验室预约 更简单的时段选择。项目源码开源https://gitee.com/codenestFlow/HarmonyOSHub二、Header SectionTitleHeader 是设备预约单行系列标准。SectionTitle 是参数化标题选择时段/预约记录两个区块Builder SectionTitle(title: string) { Row() { Text(title).fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text) } .width(100%) }两个 SectionTitle 分隔操作区选时段提交和记录区预约记录——区块标题 操作/历史的分界。三、SlotCard4 时段 Flex 真单选本页核心SlotCard 是 4 个时段胶囊的Flex 换行 真单选Builder SlotCard() { Column({ space: 12 }) { Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start }) { ForEach(this.slots, (s: string) { Text(s) .fontSize(13) .fontColor(this.slot s ? C.primary : C.textSub) .padding({ left: 14, right: 14, top: 8, bottom: 8 }) .backgroundColor(this.slot s ? C.primarySoft : C.cardSoft) .borderRadius(16) .border({ width: 1, color: this.slot s ? C.primary : C.stroke }) .margin({ right: 10, bottom: 10 }) .onClick(() { this.slot s; }) }, (s: string) s) } .width(100%) } .width(100%) .padding(14) .backgroundColor(C.card) .borderRadius(D.rLg) .border({ width: 1, color: C.stroke }) }3.1 4 时段数据State slot: string 09:00-11:00; private slots: string[] [09:00-11:00, 11:00-13:00, 14:00-16:00, 16:00-18:00];4 个时段连续覆盖一天09:00-11:00上午11:00-13:00午间14:00-16:00下午16:00-18:00傍晚State slot: string 09:00-11:00 默认选中第一时段——默认选第一个是时段选择的标准减少用户操作。3.2 真单选交互onClick(() { this.slot s; })—— 点击时段 →slot更新 ——4 个胶囊的选中态实时变化Text(s) .fontSize(13) .fontColor(this.slot s ? C.primary : C.textSub) .backgroundColor(this.slot s ? C.primarySoft : C.cardSoft) .borderRadius(16) .border({ width: 1, color: this.slot s ? C.primary : C.stroke })选中态三件套文字深青 vs 灰背景浅青C.primarySoftvs 浅灰C.cardSoft边框深青 1vp vs 浅灰 1vp真单选 点击即切换 提交按钮回显App 22 投票是真单选 锁定App 23 是真单选 回显但无锁定——真单选是State 状态驱动选中的实现。3.3 Flex 换行Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start })—— 4 个时段自动换行4 个在窄屏可能 1 行放不下——margin({ right: 10, bottom: 10 })胶囊间距。justifyContent(FlexAlign.Start)—— 从左上角排列不居中——换行内容左对齐是 Flex 布局的标准。四、SubmitBtn动态回显时段SubmitBtn 是确认预约按钮成功提示回显当前选中时段Builder SubmitBtn() { Button(确认预约) .width(100%).height(48) .fontSize(16).fontColor(#FFFFFF).backgroundColor(C.primary) .borderRadius(D.rMd) .onClick(() { promptAction.showToast({ message: 预约成功: 明天 this.slot }); }) }预约成功: 明天 this.slot—— 成功提示拼接当前时段预约成功: 明天 14:00-16:00——动态回显让用户确认我约的是这个时段——与 App 14 场地预约篮球场 19:00-20:00 预约成功同款回显。this.slot从 State 读取—— 用户选了哪个时段提交就回显哪个——State 状态驱动。与 App 14 的差异App 14 有场次姓名双校验App 23无校验时段默认已选无需校验——**默认选中 免校验**是默认值设计的好处。五、BookingList预约记录列表BookingList 是 4 条预约记录待使用橙/已完成绿Builder BookingList() { Column({ space: 12 }) { ForEach(this.bookings, (b: Booking) { Row({ space: 12 }) { Text(b.device).fontSize(28) Column({ space: 4 }) { Text(b.date b.slot).fontSize(14).fontColor(C.text) Text(b.status).fontSize(12).fontColor(b.statusColor) } .alignItems(HorizontalAlign.Start).layoutWeight(1) } .width(100%) .padding(14) .backgroundColor(C.card).borderRadius(D.rMd) .border({ width: 1, color: C.stroke }) .onClick(() { promptAction.showToast({ message: b.device }); }) }, (b: Booking) b.id.toString()) } .width(100%) }5.1 4 条记录的数据private bookings: Booking[] [ { id: 1, device: 高倍显微镜, date: 今天, slot: 14:00-16:00, status: 待使用, statusColor: C.warn }, { id: 2, device: ⚡ 示波器, date: 明天, slot: 09:00-11:00, status: 待使用, statusColor: C.warn }, { id: 3, device: 液相色谱仪, date: 昨天, slot: 14:00-16:00, status: 已完成, statusColor: C.ok }, { id: 4, device: 光谱分析仪, date: 8月10日, slot: 11:00-13:00, status: 已完成, statusColor: C.ok } ];4 条记录的设备 日期 时段 状态设备日期时段状态 高倍显微镜今天14:00-16:00待使用橙⚡ 示波器明天09:00-11:00待使用橙 液相色谱仪昨天14:00-16:00已完成绿 光谱分析仪8月10日11:00-13:00已完成绿2 待使用 2 已完成——待使用 未来预约、已完成 历史使用——预约记录的生命周期。2 状态 2 色待使用橙/已完成绿——待办用橙、完成用绿系列标准。记录卡 2 列左 emoji 右日期时段和状态——设备 时间 状态3 信息。5.2 与 Func1Tab 近期预约的跨页对应预约页记录今天 14:00-16:00 待使用 设备详情页近期预约今天 14:00-16:00 已被预约——设备详情页的近期预约 预约页的记录——跨页数据一致同一时段同一状态。六、State 与预约流程闭环Func2Tab 只有1 个 Stateslot选中时段——1 个 State 驱动时段选中 提交回显。预约流程闭环首页找设备→ 设备详情看参数→ 预约页选时段 确认→ 记录看历史找 → 看 → 选 → 记4 步预约闭环——App 23 的 4 个 Tab 承担 4 步首页找、设备看、预约选、我的记——Tab 分工 业务闭环。七、时段选择的业务规则设计App 23 的 4 个时段09:00-11:00 / 11:00-13:00 / 14:00-16:00 / 16:00-18:00是连续时段——真实预约系统的时段规则有 3 种1. 固定时段App 23——系统预设 4 个时段用户选一个——简单、可控、防冲突适合实验室统一管理。2. 自由时间——用户输入起止时间如 10:30-12:00——灵活、但冲突检测复杂需实时校验重叠。3. 时长预约——用户选开始时间 使用时长14:00 开始用 2 小时——介于两者之间起点自由、时长固定。固定时段 vs 自由时间的取舍固定时段实现简单、管理规范、用户选择成本低4 选 1自由时间用户灵活、但需要时间选择器 实时冲突检测实验室场景适合固定时段——实验室设备统一管理固定时段方便调度和统计每个时段 2 小时是标准的实验课时长。真实项目的时段配置// 时段从配置读取可按设备配置不同时段 private getSlots(deviceId: number): string[] { return slotConfig[deviceId] ?? [09:00-11:00, 11:00-13:00, 14:00-16:00, 16:00-18:00]; }时段可配置——不同设备不同时段精密仪器晚间可用、普通设备白天可用——业务规则可配置是预约系统的灵活性。八、预约记录的状态机与操作App 23 预约记录有 2 状态待使用/已完成——真实预约记录有完整状态机待使用已预约还没用 → 使用中开始使用 → 已完成使用结束 ↘ 已取消用户取消 ↘ 已过期没来也没取消5 状态的 UI 差异状态颜色操作待使用橙取消预约使用中蓝/主色结束使用已完成绿查看评价已取消灰无已过期红重新预约状态机 操作集映射系列记录页反复强调——App 23 只有待使用/已完成2 状态 无操作按钮只有点击 Toast——最简记录页。真实预约记录的操作待使用 →取消发短信/推送给管理员使用中 →签到确认到场已完成 →评价设备状态反馈记录 状态机 操作——读者做预约类 App 时记录页要按状态机设计操作。九、App 23 与 App 14 场地预约的对比App 23 实验室预约与 App 14 运动场地预约是同类预约应用——对比维度App 14 场地预约App 23 实验室预约主题色绿 #16A34A深青 #0F766E预约对象场地篮球场/足球场设备显微镜/示波器首页5 块Hero/入口/周图/场地/排行3 块Chip/Grid时段选择2 列 Grid 三态可选/已选/已满Flex 换行单选4 时段详情页无独立详情4 卡详情身份/参数/说明/预约状态空闲/已约满空闲/使用中/维护中个人中心6 块含签到4 块最简两类预约 App 的差异根源App 14 运动内容型行动型混合——首页要营销推荐场地、个人中心要留存签到App 23 实验室纯任务型——首页只要列表、个人中心只要统计预约对象决定 App 形态——场地预约偏消费休闲、设备预约偏工作科研——消费型预约丰富、工作型预约极简。十、预约提交的完整校验链App 23 的 SubmitBtn 无校验默认选中时段——真实预约提交应有完整校验链1. 设备状态校验——这台设备现在可预约吗空闲才可约、维护中拦截if (device.status 维护中) { toast(设备维护中暂不可预约); return; }2. 时段冲突校验——这个时段有人约了吗前端预检 后端最终校验if (isSlotBooked(deviceId, date, slot)) { toast(该时段已被预约请选择其他时段); return; }3. 用户资格校验——用户有权限预约这台设备吗特殊设备需导师授权。4. 预约数量校验——用户同时段预约上限防刷。设备状态 时段冲突 用户资格 数量上限4 层校验——真实预约系统的完整防线——App 23 默认选中免校验是默认值设计的简化真实项目后端校验不可少。十一、预约记录的降序与分页App 23 的预约记录是 4 条硬编码——真实预约记录需要降序 分页1. 按日期降序// 真实项目最新预约在前 const sorted bookings.sort((a, b) new Date(b.createdAt) - new Date(a.createdAt) );2. 分页加载// 上滑加载更多 Scroll() { List() { ... } .onReachEnd(() { this.page; this.loadMoreBookings(); }) }3. 状态分组进阶按待使用/已完成/已取消分组显示或 Tab 筛选。降序 分页 分组是预约记录页的 3 个真实需求——App 23 只有 4 条硬编码无排序/分页——记录列表的数据管理是真实项目的必修课。十二、预约成功的后续流程App 23 点击确认预约只弹 Toast——真实预约成功后有完整后续流程1. 生成预约凭证——预约单号 二维码到实验室扫码核销。2. 通知相关方——预约人提醒、实验室管理员审批/准备。3. 状态流转——预约 → 待使用记录列表出现→ 使用 → 完成。4. 积分/信用可选——按时履约 信用、放鸽子 -信用科研预约的信用体系。预约成功 ≠ 结束——后续的凭证 通知 流转 信用才是完整预约系统——App 23 的预约成功是入口真实系统是预约闭环。十三、Flex 换行 vs Grid 的时段选择器App 23 的 SlotCard 用Flex({ wrap: FlexWrap.Wrap })换行布局——对比系列其他选择器的布局App选择器布局数量App 18 兴趣10 标签多选Flex 换行10 个App 19 分类8 分类多选Flex 换行8 个App 21 题型4 单选Row 一行4 个App 22 时段4 时段单选Flex 换行4 个App 23 时段4 时段单选Flex 换行4 个App 16 商品6 商品单选Grid 3 列6 个Flex 换行 vs Grid的选择Flex 换行App 23标签长短不一、数量 4-10 → 自动换行宽度自适应内容GridApp 16卡片等宽、需要整齐网格 → 固定列数宽度均分时段选择器用 Flex 换行是合理选择——时段标签长度固定09:00-11:009 字符Flex 换行排成 2-3 行整齐胶囊——标签类选择器用 Flex、卡片类选择器用 Grid。App 22 和 App 23 的时段选择都用 Flex 换行——时段胶囊 Flex 换行是时段选择的稳定模式对比 App 14 场次 Grid 三态是复杂时段。十四、预约记录的设备 时间双信息App 23 预约记录卡是设备 时间 状态3 信息——预约记录必含设备和时间记录卡的信息架构设备 emoji28sp——约的什么日期 时段14sp——什么时候用状态12sp 状态色——现在什么状态设备 时间 状态3 要素是预约记录的标配——用户扫一眼知道昨天约了显微镜 14:00-16:00已完成。对比系列其他记录卡App 14 场地记录场地 时间 状态App 15 分类记录物品 分类 状态App 16 兑换记录商品 积分 状态App 23 预约记录设备 时间 状态记录卡 业务对象 时间 状态——3 要素是所有记录列表的通用信息架构——读者做任何记录预约/订单/日志都按这 3 要素设计。十五、总结App 23 预约页解析完毕。4 时段 Flex 真单选State slot 提交动态回显 预约记录 2 状态是核心组件。默认选中第一时段 免校验是默认值设计的好处。预约 4 层校验、记录降序分页、预约成功后续流程、Flex vs Grid 选择器、记录 3 要素是真实预约系统的进阶能力。找 → 看 → 选 → 记4 步预约闭环是预约类 App 的标准流程。
返回列表