摘要地区分库页面看起来简单却承担着稳定身份、路由可达和共享组件复用三项关键职责。本文基于“中国方言题库”真实源码中的SichuanBankPage.ets沿着BankCard - SichuanBankPage - BankDetailContent - PracticePage追踪b_sichuan说明如何用薄入口组件复用题库详情、学习进度、章节列表和多设备布局同时避免复制业务代码、路由参数污染与地区数据串库。一、只有十几行的页面为什么值得单独分析SichuanBankPage.ets的全部核心代码非常短import { BankDetailContent } from ./BankDetailPage Entry Component struct SichuanBankPage { build() { Column() { BankDetailContent({ fixedBankId: b_sichuan }) } .width(100%) .height(100%) } }它没有自己加载题目、计算进度、渲染章节也没有再次实现随机练习和模拟考试。页面只做两件事作为 ArkUI 路由入口存在。把稳定地区 IDb_sichuan注入共享详情组件。这种“薄入口”不是代码不足而是有意保持职责单一。本文的唯一标记是地区入口只负责固定题库身份。所有可复用业务都留在BankDetailContent四川话差异来自目录和文化档案而不是复制一份详情页后再修改文案。二、完整调用链从题库卡片开始首页和题库列表使用BankCard。卡片根据bank.id决定目标页private detailPageUrl(): string { switch (this.bank.id) { case b_sichuan: return pages/SichuanBankPage case b_yue: return pages/YueBankPage case b_northeast: return pages/NortheastBankPage case b_shanghai: return pages/ShanghaiBankPage case b_minnan: return pages/MinnanBankPage case b_hakka: return pages/HakkaBankPage default: return pages/BankDetailPage } }点击四川话卡片时router.pushUrl({ url: this.detailPageUrl(), params: { bankId: this.bank.id } })虽然路由仍携带bankId四川话固定入口不会依赖它。BankDetailContent.aboutToAppear()先检查fixedBankIdif (this.fixedBankId.length 0) { this.bank getBankById(this.fixedBankId) return }只有未传固定 ID 时通用BankDetailPage才读取 Router 参数。这条优先级保证即使页面栈中残留了其他地区参数SichuanBankPage仍只能展示四川话题库。三、固定参数比页面内部常量更容易复用一种常见写法是在详情组件内部判断当前页面名称或在每个地区页面复制一套 UI。当前工程选择属性注入BankDetailContent({ fixedBankId: b_sichuan })优点包括详情组件可以独立测试不同fixedBankId。地区入口无需知道详情实现。通用详情页仍可支持动态bankId。六个入口结构保持一致。地区身份在组件创建处一眼可见。如果把四川 ID 隐藏在全局变量或 AppStorage 中页面恢复时容易读到上一个地区如果把它写进BankDetailContent内部又会破坏组件复用。属性传递是最窄、最明确的依赖。四、六个地区入口保持同构工程中还存在YueBankPage - b_yue NortheastBankPage - b_northeast ShanghaiBankPage - b_shanghai MinnanBankPage - b_minnan HakkaBankPage - b_hakka每个页面都采用相同根布局与共享组件。这样做能让 AppGallery 的多设备适配、系统返回和稳定性修复一次覆盖六个分库。同构不等于可以手工随意复制。复制入口文件后最常见的错误是文件名改了fixedBankId没改导致“粤语题库”入口打开四川话内容。建议为入口建立表驱动测试页面预期 ID预期名称SichuanBankPageb_sichuan四川话题库YueBankPageb_yue粤语题库NortheastBankPageb_northeast东北话题库ShanghaiBankPageb_shanghai上海话题库MinnanBankPageb_minnan闽南语题库HakkaBankPageb_hakka客家话题库五、路由清单是入口可达性的第二个真源只有Entry还不够页面必须注册在main_pages.json{ src: [ pages/BankDetailPage, pages/SichuanBankPage, pages/YueBankPage, pages/NortheastBankPage, pages/ShanghaiBankPage, pages/MinnanBankPage, pages/HakkaBankPage ] }页面文件、路由字符串和清单路径必须完全一致。重命名文件后只改 import不改清单编译可能通过部分阶段但运行跳转会失败。发布前应自动检查BankCard 返回的每个 pages/... 路径 必须存在于 main_pages.json 且对应 .ets 文件真实存在这是很适合写成静态脚本的规则不需要每次靠人工逐个点击才能发现拼写错误。六、题库目录中b_sichuan的真实内容MockBanks.ets将四川话地区与题库分开建模{ id: sichuan, name: 四川话, shortName: 川, cover: ... } { id: b_sichuan, regionId: sichuan, name: 四川话题库, totalCount: 0, accuracy: 0, hot: 98, chapters: SICHUAN_CHAPTERS }地区 ID 是sichuan题库 ID 是b_sichuan。入口传递的是题库 ID因为详情页需要查找章节、题目与学习进度。混用两个 ID 会导致getBankById()返回undefined页面进入“未找到题库”空态。四川话题库包含六个章节基础词汇 日常生活 人称称谓 饮食词汇 俗语歇后语 麻将与娱乐题量并非永久写死在 Bank 模型中。目录初始化时从去重后的真实题目集合回填totalCount和章节总量。分库页显示的“共 N 题”因此应与练习页可用题目保持一致。七、四川话文化差异来自 Profile而不是页面分支共享详情组件通过BANK_DETAIL_PROFILES查找四川话档案[b_sichuan, { subtitle: 巴适表达、茶馆闲谈和川味生活都在这里, intro: 四川话题库偏重高频口语、称呼调侃和饮食表达适合先从有画面感的词句入门。, cultureNote: 会结合茶馆、火锅、麻将社交等语境帮助理解“摆龙门阵”“巴适”这类代表性说法。, focusTags: [高频口头词, 饮食表达, 俗语语感], sceneTags: [茶馆聊天, 火锅点单, 朋友调侃] }]页面结构仍然是 Hero、学习进度、简介、文化提示、重点标签和章节列表。只替换档案数据就能形成地区识别度。文化内容需要人工校对。比如熟人之间的调侃不一定适合正式场合同一表达在四川不同地区也可能有差异。代码能保证字段存在却不能自动证明文化解释具有普遍性。内容维护应记录适用语境和审核来源。八、学习进度通过题库 ID隔离共享组件使用UserDataManager.getProgress(this.progressList, this.bankId())章节进度使用题库 ID 与章节 ID 联合查询UserDataManager.getChapterProgress( this.chapterProgressList, this.bankId(), chapter.id )这意味着b_sichuan不只是展示参数也是本地学习状态的分区键。若写入时使用sichuan读取时使用b_sichuan用户完成练习后详情页仍会显示 0。建议把 ID 类型收紧减少任意字符串export type BankId | b_sichuan | b_yue | b_northeast | b_shanghai | b_minnan | b_hakkaArkTS 工程也可以用常量对象统一引用避免入口、目录、Profile 和测试中重复手写字符串。九、共享详情保留多设备能力四川话入口没有自己的断点判断但它复用了BankDetailContent的适配能力。当currentBp lg且页面宽度不小于 700vp 时详情页使用双栏左栏封面、学习摘要、题库简介。右栏学习重点、常见语境、章节练习。其他窗口使用单列滚动。底部随机练习与模拟考试按钮根据系统导航指示区计算安全距离。这正是复用的价值如果六个地区各自实现详情页任何底部安全区、横屏或 2in1 修复都要改六次。现在只需修正共享组件固定入口自然获得同一行为。十、薄入口仍需要稳定根容器SichuanBankPage外层使用Column() { BankDetailContent({ fixedBankId: b_sichuan }) } .width(100%) .height(100%)根容器满宽满高确保内部详情可以正确计算onAreaChange和滚动区域。若只依赖子组件自然尺寸宽屏断点可能得到错误宽度底部操作栏也可能无法贴合页面底部。入口没有额外背景和 padding避免与共享组件的背景、TopBar 和安全区重复。薄入口应尽量透明不在外层再增加一层卡片或滚动容器。十一、从分库进入三种练习模式在共享详情中四川话题库可以进入// 章节练习 { bankId: b_sichuan, chapterId, mode: chapter } // 随机练习 { bankId: b_sichuan, mode: random } // 模拟考试 { bankId: b_sichuan, mode: exam }参数链路中bankId必须保持不变。PracticePage 应先校验题库再根据 mode 选择题目chapter 只使用对应章节题目。random 从四川话题库真实题目中抽取。exam 按当前可用题量组成试卷。不能因为入口是四川话专属页面就让 PracticePage 依赖“上一页是什么”。目标页只应信任明确参数这样从搜索、收藏或恢复页面进入时仍能工作。十二、为何不直接统一成一个动态详情路由既然通用BankDetailPage能读取bankId为什么还保留六个固定入口当前设计可能有以下工程考虑每个地区需要稳定、可独立注册的页面地址。后续可能加入地区专属资源或入口配置。固定页面可防止路由参数被错误覆盖。页面统计或测试可以按地区入口分别执行。代价是路由文件和清单条目增多。若未来地区数量从 6 增长到 50继续为每个地区创建页面会产生维护负担。那时可以改为一个类型安全的动态详情页并在 Navigation 中统一路由契约。当前只有六个地区薄入口模式仍然简单可控。不要因为追求“零重复”过早引入复杂路由框架。十三、switch 映射可以进一步集中BankCard.detailPageUrl()当前用 switch 将题库 ID 映射到页面。入口文件和清单新增后还要记得修改 switch。可以用结构化 Map 减少分散配置const BANK_DETAIL_ROUTES: Mapstring, string new Map([ [b_sichuan, pages/SichuanBankPage], [b_yue, pages/YueBankPage], [b_northeast, pages/NortheastBankPage], [b_shanghai, pages/ShanghaiBankPage], [b_minnan, pages/MinnanBankPage], [b_hakka, pages/HakkaBankPage] ]) function detailRoute(bankId: string): string { return BANK_DETAIL_ROUTES.get(bankId) || pages/BankDetailPage }更进一步可以把 route 加入 Bank 元数据但要避免让纯业务模型过度依赖页面路径。若目录模型还要在非 UI 模块复用路由映射留在导航层更合适。十四、空态不是“不会发生”即使固定 ID 写在源码中仍可能因为目录重命名、题库移除或初始化失败而找不到。共享详情会显示“未找到题库”不会崩溃。对于固定入口这种情况属于工程配置错误不只是普通空数据。调试构建可以记录SichuanBankPage fixedBankIdb_sichuan getBankById resultundefined发布构建不应展示内部路径或堆栈但可以提供返回题库列表的操作。自动化测试应让所有固定 ID逐一通过getBankById()在构建前发现配置断裂。十五、入口测试比截图更重要四川话分库至少需要以下测试身份测试打开 SichuanBankPage 后标题为“四川话题库”。Hero 封面来自四川话资源。文化档案包含四川话语境而非其他地区。六个章节名称与四川目录一致。参数测试路由传入b_yue时固定入口仍展示b_sichuan。通用 BankDetailPage 传b_sichuan时得到相同详情内容。不存在的固定 ID进入空态。练习页收到的 bankId 始终为b_sichuan。状态测试完成四川话题目后只更新四川话进度。粤语进度不会出现在四川话页。完成章节后按钮与进度立即更新。重启应用后本地进度可恢复。适配测试手机单列与底部操作正常。平板和 2in1 双栏切换正常。大字体下标签和章节标题不重叠。系统导航区不会遮挡练习按钮。十六、参数串库的典型症状和定位顺序若用户点击四川话却看到粤语内容按以下顺序排查BankCard的bank.id是否为b_sichuan。detailPageUrl()是否返回pages/SichuanBankPage。main_pages.json是否注册正确页面。SichuanBankPage是否注入b_sichuan。getBankById(b_sichuan)是否返回四川题库。BANK_DETAIL_PROFILES的 key 是否为同一 ID。本地进度写入是否也使用b_sichuan。PracticePage 是否继续沿用传入 ID。不要一开始就怀疑 ArkUI 状态刷新。先沿 ID 链逐层核对通常能在很小范围内找到错配。十七、薄入口的性能成本很低SichuanBankPage本身不复制数据也不创建额外服务只实例化共享组件并传递字符串属性。运行时主要成本仍来自详情页的图片、列表、进度计算和滚动布局。性能优化应落在共享层题库查询使用稳定索引。章节进度按 ID 快速查找。封面提供适合展示尺寸的资源。状态变化时避免反复遍历大量历史。宽屏两栏不重复构建同一内容。不要为了优化十几行入口而引入全局缓存那不会解决真正的渲染成本。十八、上架材料中的真实能力边界根据当前源码可以准确描述四川话拥有独立可达的题库入口。入口复用统一详情组件。地区身份固定为b_sichuan。页面展示四川话简介、文化提示、重点、语境和章节。学习进度来自本地记录。支持章节、随机和考试三种练习入口。共享详情适配 phone、tablet、2in1。不能因为有独立页面就声称四川话分库拥有独立网络服务、独立账号或独立云题库。当前差异来自包内目录、题目和文化档案。十九、可复用的地区入口模板新增一个地区时最小步骤是1. 在题库目录定义唯一 Bank ID 2. 添加题目和章节并同步真实数量 3. 增加文化 Profile 4. 创建薄入口并注入固定 ID 5. 注册 main_pages.json 6. 在导航映射中增加路径 7. 验证详情、进度和三种练习模式 8. 完成 phone、tablet、2in1 适配回归每一步都围绕同一 ID。只要 ID 在目录、Profile、入口、路由、持久化和练习页保持一致地区扩展就不会演变成六套独立业务。二十、总结四川话分库最值得复用的不是一段复杂算法而是一条清晰边界入口固定身份共享组件承担详情业务目录和文化档案提供差异练习页只依赖显式参数。SichuanBankPage虽然只有十几行却把地区身份稳定地接入了完整学习链路。对于 HarmonyOS 5.0 以上的 ArkUI 工程薄入口模式尤其适合“结构相同、内容不同”的模块。它减少重复保留独立路由又让多设备适配、底部安全区、进度展示和异常空态可以集中修复。真正需要严格维护的不是页面代码量而是b_sichuan这条参数链在所有层级中始终一致。---AI 辅助声明本文由 AI 辅助整理所有结论基于中国方言题库当前SichuanBankPage、共享详情组件、题库目录、路由清单和练习参数真实源码复核未将薄入口描述为独立业务或云端能力。