当前位置: 首页 > news >正文

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 才不会越写越乱。

http://www.cnnetsun.cn/news/3302897.html

相关文章:

  • 学生信息管理系统结构化需求分析:从7个非功能性需求到3级数据流图
  • 【Bug已解决】openclaw git integration failed / Cannot detect repository — OpenClaw Git 集成失败解决方案
  • Spring Cloud - 黑马商城
  • 蓝桥杯国赛深度反思:如果重来一次,我会这样优化备赛计划
  • 华为S5700交换机VLAN配置实战:基于700人企业网络的5步优化方案
  • 2026湖南GEO网站定制开发公司最新推荐:实地探访聚之唯,拆解AI时代官网开发的技术内幕
  • Seedream 5.0 Pro多模态图像生成模型:从技术原理到数据可视化实战
  • Cartographer 建图到导航实战:从 .pbstream 到 ROS 地图的 2 种转换方法与 Nav2 集成
  • 数据中心AI化转型:技术架构演进与社会影响深度解析
  • NLP入门实战:Word2Vec词向量与RNN/LSTM情感分类完整指南
  • VSCode 1.90 代码片段进阶:3种头文件保护宏命名规则与变量解析
  • Spark 3.5 核心算子性能对比:map vs mapPartitions 在 10GB 数据集上的吞吐量差异
  • 遗传算法实战:从编码选择到动态参数调优的工程落地路径
  • sychronized 的自旋锁、偏向锁、轻量级锁、重量级锁,分别介绍和联系
  • 4K短片《潮湿的怒火》:艾滋病恐惧与社会偏见的心理写实
  • iOS激活锁绕过神器:applera1n免费工具完全指南
  • 2025年最强微信小程序反编译工具:unveilr 2.0.0完全解析指南
  • MoE模型prefill并行化:专家并行架构与vLLM优化实践
  • 深度解析:抖音GEO优化与短视频SEO技术机制——从RAG检索到算法权重重构 2026年的抖音,不刷是损失,不搜才是。
  • 数据加密与参数签名分析:常见加密算法、签名逻辑与逆向分析思路实战
  • 机器学习第一次作业-Numpy
  • 如何快速构建多平台音乐解析服务:终极实践指南
  • Windows 11 网络排错实战:5步法定位问题,Ping/Tracert/Netstat 组合拳
  • 终极免费方案:如何让《植物大战僵尸》完美适配现代宽屏显示器
  • Bacformer源码解读:基因组级蛋白质语义建模技术解析
  • EM3080-W与PIC32MX695F512L在工业条码识别中的硬件设计与优化
  • 题解:Atcoder Weekday Contest awc0110 E - Abbreviation Assignment
  • Windows 11 / macOS Sonoma 系统下:3 款主流杀软对 10 类木马的查杀率实测对比
  • YOLOv8环境配置与自定义数据集训练全流程实战指南
  • MongoDB 删除操作深度对比:deleteOne、deleteMany、remove 与 drop 的 4 种场景选择指南