news 2026/7/12 3:16:40

ArkUI 筛选清空后列表还乱怎么办:中式美食关键词、分类和排序状态怎么收口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ArkUI 筛选清空后列表还乱怎么办:中式美食关键词、分类和排序状态怎么收口

用户先搜“牛肉”,再点“家常菜”,又切到“收藏优先”,最后点“清空”。如果页面还保留旧关键词,或者列表标题显示已清空但结果还是分类后的数据,这个体验会很糟。中式美食的搜索、分类、推荐、收藏都会碰到类似问题。ArkUI 页面写起来很快,但筛选状态如果散在多个组件里,后面一定会出现“清空了却没真清空”的问题。

应用名称中式美食
这篇解决什么关键词、分类、排序、分页混在一起后,清空筛选不彻底
谁会搜这篇做 HarmonyOS 列表页、搜索页、分类页、筛选条的 ArkUI 开发者
点进来能拿到什么筛选状态模型、reset 规则、ViewModel 输出和验收用例
当前项目证据SearchViewModel、搜索历史/热门词/结果状态、购物清单列表状态
HarmonyOS 目标能力ArkUI、ArkTS、ViewModel、ForEach、List、状态收口

本章导读

这篇不讲花哨筛选组件,只讲一个真实问题:清空筛选后列表到底应该回到什么状态。中式美食这种应用,列表入口多,筛选条件也多。关键词、分类、排序、分页、空状态如果各管各的,页面很快就会出现互相打架。

章节重点
问题从哪里来为什么组件里各存一份状态会乱
状态模型怎么定用一个FilterState收口关键词、分类、排序
reset 怎么写清空不是只清输入框,还要清分页和空态
ArkUI 怎么接页面只展示状态,不自己拼条件
怎么验收搜索、分类、排序、清空、返回都要测

当前验证环境和技术栈

项目说明
DevEco Studio6.x 系列
HarmonyOS SDKAPI 12/ArkTS 工程
UI 层ArkUI 声明式页面
状态层ViewModel 统一输出列表状态
当前项目参考中式美食搜索页、分类列表、推荐流、购物清单
验收方式固定操作链路:搜索、分类、排序、清空、返回

当前中式美食搜索 ViewModel 已经把历史词、热门词和搜索结果分成不同状态。这个方向是对的。下一步要补的是筛选条件本身也要收口。

Future<void>search(Stringkeyword,{int page=1})async{state=state.copyWith(keyword:keyword,results:constUiState.loading());try{finalresult=await_repository.search(keyword,page:page);state=state.copyWith(results:result.items.isEmpty?constUiState.empty('没有找到相关菜谱'):UiState.success(result),);}catch(error){state=state.copyWith(results:UiState.error(error.toString()));}}

如果后面关键词、分类、排序都各自写一个@State,清空按钮就要知道所有状态在哪里,漏一个就出问题。

先把筛选状态合成一个对象

我会先定一个RecipeFilterState。关键词、分类、排序、页码、是否只看收藏,都放在一处。页面组件不再各自保存业务条件。

typeRecipeSortMode='default'|'recent'|'favorite'|'cookTime';interfaceRecipeFilterState{keyword:string;categoryId:string;sortMode:RecipeSortMode;onlyFavorite:boolean;page:number;}constdefaultFilterState:RecipeFilterState={keyword:'',categoryId:'',sortMode:'default',onlyFavorite:false,page:1};
字段什么时候变清空时怎么处理
keyword用户输入或点历史词回到空字符串
categoryId用户点分类回到全部分类
sortMode用户切排序回到默认排序
onlyFavorite用户只看收藏回到 false
page分页加载回到第一页

这里最容易漏的是page。很多列表清空后还停在第 3 页,结果用户看到的不是默认列表前几条,而是默认条件下的第 3 页。

reset 不是只清输入框

清空按钮必须重置整份筛选状态,并重新拉取默认列表。不要只把输入框清空。

@ObservedexportclassRecipeListViewModel{filter:RecipeFilterState={...defaultFilterState};items:RecipeCardModel[]=[];loading:boolean=false;emptyText:string='';asyncresetFilter(){this.filter={...defaultFilterState};awaitthis.reload();}}

如果只是这样还不够,reload也要只读当前filter,不要让页面把临时条件传来传去。

asyncreload(){this.loading=true;this.emptyText='';try{constresult=awaitthis.repository.query(this.filter);this.items=result.items;this.emptyText=result.items.length===0?'没有找到符合条件的菜谱':'';}finally{this.loading=false;}}
操作错误写法稳定写法
清空关键词只改输入框文字重置整份filter
切分类分类组件自己存 idViewModel 更新filter.categoryId
切排序排序组件单独请求ViewModel 更新filter.sortMode后 reload
翻页页面自己拼 pageViewModel 控制filter.page
返回列表重新造默认状态保留 ViewModel 当前状态

ArkUI 组件只触发动作

页面组件不应该自己拼筛选条件。组件只负责把用户动作告诉 ViewModel。

@Componentstruct RecipeFilterBar{@ObjectLinkvm:RecipeListViewModel;build(){Row(){TextInput({text:this.vm.filter.keyword,placeholder:'搜索菜名或食材'}).onSubmit((value:string)=>this.vm.changeKeyword(value))Button('清空').onClick(()=>this.vm.resetFilter())}}}

分类和排序也同理。

asyncchangeCategory(categoryId:string){this.filter={...this.filter,categoryId,page:1};awaitthis.reload();}asyncchangeSort(sortMode:RecipeSortMode){this.filter={...this.filter,sortMode,page:1};awaitthis.reload();}

每次变更筛选条件都把page拉回 1,这样用户不会被旧分页影响。

列表渲染只相信 ViewModel 输出

列表组件只拿items,不要再二次过滤。二次过滤会让标题、空状态和数据对不上。

@Componentstruct RecipeList{@ObjectLinkvm:RecipeListViewModel;build(){List(){ForEach(this.vm.items,(item:RecipeCardModel)=>{ListItem(){RecipeCard({item})}},(item:RecipeCardModel)=>item.id)}}}
页面显示来源不要怎么做
列表数据vm.items组件里再 filter 一遍
空文案vm.emptyText页面自己猜空态原因
当前关键词vm.filter.keywordTextInput 单独维护一份
当前分类vm.filter.categoryId分类组件单独存
当前排序vm.filter.sortMode排序弹窗自己请求数据

请求乱序也要防

用户快速输入和切分类时,很容易出现后发请求先回来。这个问题不处理,列表会被旧结果覆盖。

letrequestVersion=0;asyncreload(){constcurrent=++requestVersion;this.loading=true;constresult=awaitthis.repository.query(this.filter);if(current!==requestVersion){return;}this.items=result.items;this.loading=false;}

这不是复杂优化,是列表页基本防线。搜索、分类、排序组合越多,越需要请求版本号。

工程验收

验收项操作通过标准
关键词搜索输入“牛肉”列表只显示命中结果
分类切换点“家常菜”标题、列表、空态都对应家常菜
排序切换切“收藏优先”列表顺序变化,筛选条件不丢
清空筛选点清空关键词、分类、排序、分页都回默认
快速切换连续输入和点分类最终只显示最后一次条件结果
返回列表从详情页返回原筛选状态仍在

可以把验收写成下面这种检查:

functionassertDefaultFilter(filter:RecipeFilterState){if(filter.keyword!==''){thrownewError('清空后 keyword 没有归零');}if(filter.categoryId!==''){thrownewError('清空后 categoryId 没有归零');}if(filter.sortMode!=='default'){thrownewError('清空后 sortMode 没有回默认');}if(filter.page!==1){thrownewError('清空后 page 没有回第一页');}}

常见问题和边界

问题我的处理
筛选状态要不要进 Preferences高频恢复可以进,比如最后一次分类;普通临时筛选先留 ViewModel
清空后要不要保留搜索历史搜索历史可以保留,但当前关键词必须清空
返回详情后要不要重新请求先保留原列表,再按需后台刷新
空态文案放哪里ViewModel 输出,页面不自己判断
分类和关键词能不能同时生效可以,但规则必须明确,不能组件各自决定

本章小结

中式美食的列表筛选,真正要解决的是“状态只有一个可信来源”。关键词、分类、排序、分页和空态如果散在多个组件里,清空按钮永远容易漏。看起来只是一个小交互,实际会影响搜索页、分类页、推荐流、收藏页和详情返回。

我的做法是把筛选条件合成RecipeFilterState,所有入口都通过 ViewModel 改它;页面只触发动作和展示结果;清空时重置整份状态,并把分页拉回第一页。这样写不花哨,但可以让用户明确感到:我点了什么,页面就按什么变;我点清空,页面就真的回到默认。

如果你也在做 HarmonyOS 列表页,可以先把所有筛选条件列出来,然后只允许一份状态说了算。这个规则定住,后面的 UI 才不会越写越乱。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/12 3:16:02

学生信息管理系统结构化需求分析:从7个非功能性需求到3级数据流图

学生信息管理系统需求分析实战指南&#xff1a;从理论到数据流图的完整实现在软件工程课程中&#xff0c;学生信息管理系统是最常见的课程设计选题之一。这个看似简单的系统实际上涵盖了用户角色划分、权限管理、数据流建模等软件工程核心概念。本文将带你从零开始&#xff0c;…

作者头像 李华
网站建设 2026/7/12 3:13:36

Spring Cloud - 黑马商城

第一天项目熟悉hm-common&#xff1a;用来存放使用到的工具包hm-service: 整个单体项目大差不差&#xff0c;配置层&#xff0c;控制层&#xff0c;实体&#xff0c;mapper接口&#xff0c;业务逻辑&#xff0c;配置文件微服务架构认识个人理解微服务是一个架构思想&#xff0c…

作者头像 李华
网站建设 2026/7/12 3:13:20

蓝桥杯国赛深度反思:如果重来一次,我会这样优化备赛计划

随着蓝桥杯国赛落下帷幕&#xff0c;很遗憾没有在国赛中取得很好的名次 。我总结了这次蓝桥杯过程中我在备赛策略上出现的问题&#xff0c;也是很多同学可能存在的问题。以下是我对未来准备参加蓝桥杯同学们的建议。 一、 刷题策略&#xff1a;从“暴力”起步&#xff0c;以“…

作者头像 李华
网站建设 2026/7/12 3:10:56

华为S5700交换机VLAN配置实战:基于700人企业网络的5步优化方案

华为S5700交换机VLAN配置实战&#xff1a;基于700人企业网络的5步优化方案1. 企业网络现状分析与VLAN规划必要性某技术密集型企业拥有700名员工&#xff0c;网络终端设备约1500台&#xff08;含PC、手机、打印机等&#xff09;&#xff0c;采用扁平化网络架构&#xff0c;子网掩…

作者头像 李华