【OpenHarmony/HarmonyOs 】最多选择 5 个:ArkUI 快捷入口管理弹窗完整实现

📅 2026/7/23 14:36:51
【OpenHarmony/HarmonyOs 】最多选择 5 个:ArkUI 快捷入口管理弹窗完整实现
【OpenHarmony/HarmonyOs 】最多选择 5 个ArkUI 快捷入口管理弹窗完整实现前言快捷入口的产品目标是让用户从几十个收藏中挑出最常用的少数站点。它看似是多选列表实际包含选择上限、取消选择、失效数据过滤、持久化和模态层交互。本文拆解 LinkOS 链界首页的快捷入口管理功能。⚡一、用 ID 集合保存选择StateshowQuickEntrySheet:booleanfalse;StatequickEntrySelectedIds:string[] [];privateisInQuickEntry(id:string):boolean{returnthis.quickEntrySelectedIds.includes(id); }只保存 ID而不是复制完整UrlItem。网址标题或图标修改后快捷入口仍能从最新数据源解析不会出现两份对象内容不一致。二、打开模态层Button(快捷入口) .onClick(() this.showQuickEntrySheet true)if(this.showQuickEntrySheet) {this.QuickEntrySheet() }页面根节点使用 StackSheet 位于内容上方。遮罩层覆盖全屏并支持点击关闭Stack(){ Rect().width(100%).height(100%).fill(rgba(0,0,0,0.35)).onClick(() this.showQuickEntrySheet false) Column() {/* 选择面板 */}.backgroundColor(Color.White).borderRadius(18) }.zIndex(200)点击面板内部不能冒泡关闭正式组件还要处理系统返回键、焦点锁定和屏幕旋转。三、选择与取消选择.onClick(() {constid item.id;if(this.isInQuickEntry(id)) {this.quickEntrySelectedIds this.quickEntrySelectedIds.filter(value value ! id); }elseif(this.quickEntrySelectedIds.length 5) {this.quickEntrySelectedIds [...this.quickEntrySelectedIds, id]; } })取消时使用 filter新选中时使用展开运算符创建新数组从而可靠触发State更新。业务规则很清楚已选项目始终可以取消未选项目只有在数量小于 5 时才能加入。四、按钮禁用逻辑.enabled(this.isInQuickEntry(item.id) ||this.quickEntrySelectedIds.length 5)达到上限后未选按钮禁用但已选按钮仍可点击取消。若简单写成length 5第五个项目选中后连取消按钮也会全部失效这是多选上限中常见的逻辑错误。界面还应显示当前进度Text(已选择 ${this.quickEntrySelectedIds.length}/5)五、确认后持久化await storage.put( StorageKeys.QUICK_ENTRY_URL_IDS, JSON.stringify(this.quickEntrySelectedIds) );this.showQuickEntrySheet false;Preferences 不直接支持字符串数组因此使用 JSON。读取时不能直接信任解析结果constraw awaitstorage.get(StorageKeys.QUICK_ENTRY_URL_IDS,[])asstring;try{constparsed JSON.parse(raw)asObject;if(Array.isArray(parsed)) {this.quickEntrySelectedIds parsed.filter(valuetypeofvalue string).slice(0,5)asstring[]; } }catch{this.quickEntrySelectedIds []; }slice(0, 5)可以防御旧版本或异常数据超过上限。六、保存和取消的语义如果用户在 Sheet 中点了几次选择然后点击遮罩“取消”当前实现已经修改了真实State更改仍可能保留。更严格的交互应维护草稿StatequickEntryDraftIds: string[] [];privateopenQuickEntrySheet(): void {this.quickEntryDraftIds [...this.quickEntrySelectedIds];this.showQuickEntrySheet true; }所有操作修改 Draft点击保存才覆盖正式状态取消则直接丢弃草稿。这样“取消”才真正没有副作用。七、处理已经删除的网站用户删除收藏后Preferences 中可能仍保存对应 ID。恢复时应与当前站点集合取交集constvalidIds newSet(this.getAllSites().map(item item.id));this.quickEntrySelectedIds storedIds .filter(id validIds.has(id)) .slice(0,5);否则首页可能出现空白入口计数也会显示错误。删除网址时也可以主动同步清理快捷 ID。八、顺序问题数组天然保存选择顺序但用户可能希望拖动排序。可将选择结果定义为有序 ID 列表渲染时按 ID 顺序查找对象。未来加入拖拽只需调整数组顺序不需要修改数据模型。九、完整状态清单尚未选择保存按钮禁用还是允许清空需要产品明确选择 1 至 4 个可继续选择已选 5 个未选项禁用已选项可取消收藏为空展示空状态和添加入口某条已删除自动清除失效 IDJSON 损坏回退为空保存失败面板不应直接关闭应允许重试。十、总结快捷入口管理的核心是“有序 ID 集合 上限规则 草稿提交 数据清洗”。特别要注意达到上限后仍允许取消、关闭弹窗不应意外保存以及删除收藏后清除失效 ID。把这些边界处理完整一个普通多选面板才会变成可靠的产品功能。✅