自由窗口一缩放页面就重新请求?把窗口布局状态和业务数据状态拆开

应用进入鸿蒙电脑自由窗口后,用户拖一下边框,列表就闪白并重新请求;连续缩放几次,后台同时出现多条相同接口。自由窗口本身支持拖拽和缩放,窗口尺寸变化是正常交互,不应被当成页面重新进入。需要迁移的不是一条断点规则,而是状态所有权。

验证边界:本文核对了华为开发者官网截至 2026-09-24 可访问的资料。官方事实与文中的纯函数示例分开说明:示例逻辑已在 Node.js 宿主环境运行,当前本机仍是 API 24 SDK 且没有连接 HDC 真机,因此不把示例称为 API 26 编译或真机实测;正式交付必须在 API 26 SDK、目标设备或对应模拟器上补齐验证。

自由窗口缩放与业务状态分层架构图

旧判断为什么失效

旧页面常在 aboutToAppear 或尺寸分类变化时同时初始化布局和加载数据。窗口从 medium 到 expanded 再回 medium,组件树变化触发初始化,业务请求、筛选条件和滚动位置一起重置。这个写法在固定全屏设备上不明显,到了自由窗口就会被高频尺寸事件放大。

先建立迁移模型

把业务仓库放在稳定页面或路由作用域,把窗口尺寸只转换成布局模式。布局组件可重建,但数据请求由查询键和缓存世代决定;滚动位置按内容 ID 保存,而不是按像素保存。

type Mode = 'compact'|'medium'|'expanded';
export function modeFor(width:number): Mode {
  return width < 600 ? 'compact' : width < 1000 ? 'medium' : 'expanded';
}
interface QueryState { key:string; loading:boolean; loadedAt:number }
export function shouldLoad(s:QueryState, key:string, now:number): boolean {
  return s.key !== key || (!s.loading && now - s.loadedAt > 60_000);
}

设备案例一:列表从单栏切到双栏

只替换布局容器,列表数据和筛选条件继续来自同一个仓库。当前选中项用稳定 ID 传给详情栏;从双栏缩回单栏时,把这个 ID 变成可返回的详情路由,而不是丢弃。

设备案例二:拖动边框经过多个断点

尺寸事件先去抖,再只在布局模式真正改变时重排。即使模式改变,查询键不变也不重新请求;仍在进行的请求只由查询世代控制,窗口变化不取消业务任务。

新旧方案怎么选

观察项容易误判可复核做法
尺寸事件每次触发整页初始化去抖并只更新布局模式
数据请求组件出现就请求查询键、缓存和世代共同决定
选择状态跟着右栏组件销毁由页面仓库保存稳定 ID
滚动恢复保存像素 offset保存可见内容 ID 与相对位置

布局状态是短生命周期的视图事实,业务状态是跨布局连续的用户任务。拆开后,自由窗口、平板分屏和横竖屏都能复用同一套数据层。

迁移验收清单

  • 连续缩放不会重复发起相同请求。
  • 断点变化只影响布局,不清空筛选。
  • 单栏与双栏切换保留选中项。
  • 异步结果按查询世代验收。
  • 窗口恢复后滚动锚点仍指向同一内容。

官方资料

自由窗口把过去偶发的配置变化变成持续交互。只要窗口一动业务就重置,说明状态边界还没有真正建立。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐