文章导读

  • 搜索页同时覆盖资讯和装备两个维度,结果页通过 SegmentTab 切换。
  • 远程数据优先展示,本地数据作为兜底补充,并通过 id 去重。
  • 空关键字、无结果和有结果三种状态都要明确,不然搜索页会显得没有反馈。

页面效果

搜索页最容易让用户感到“有没有结果一眼看不出来”。羽球联盟把搜索反馈拆成两个层次:先在顶部提示当前命中数量,再在正文区域按照资讯和装备两个 Tab 展示结果。这样用户既知道搜到了什么,也知道没搜到时系统在做什么。
搜索结果

从页面角度看,搜索结果其实并不复杂;真正复杂的是数据源。这个项目既有内置的资讯与装备数据,也有联网刷新后的远程数据。如果只是简单把两个数组拼接起来,重复项、空态和排序问题都会一起冒出来。

实战拆解

SearchResultPage 的思路很清楚:先把所有可搜索的数据合并成一份候选池,再根据关键字分别筛出资讯结果和装备结果。资讯用 allArticles(),装备用 allEquipments();如果远程数据为空,直接回退到本地内置列表,如果远程数据存在,就先保留远程项,再把本地未覆盖到的内容补进来。

这样做有两个明显好处。第一,远程抓取到的新资讯会优先出现,搜索结果和首页刷新后的新鲜度保持一致。第二,本地静态数据不会因为远程列表不完整而丢失,尤其是装备这类类别跨度比较大的数据,兜底价值很高。对教程读者来说,这比单纯演示一个 filter() 更接近真实应用场景。

搜索字段本身也不能只看标题。资讯侧除了标题,还要搜摘要、标签和作者;装备侧除了名称,还要覆盖品牌、摘要和标签。用户不一定知道一篇资讯的完整标题,但他可能记得一个品牌、一个球员名或者一个比赛标签。把这些入口都接上,搜索体验才会像一个真正可用的页面。

关键代码

private allArticles(): Article[] {
  if (this.remoteArticles.length === 0) {
    return ARTICLES;
  }
  const remoteIds: Set<string> = new Set();
  for (const a of this.remoteArticles) {
    remoteIds.add(a.id);
  }
  const merged: Article[] = [];
  for (const a of this.remoteArticles) {
    merged.push(a);
  }
  for (const a of ARTICLES) {
    if (!remoteIds.has(a.id)) {
      merged.push(a);
    }
  }
  return merged;
}

private matchedArticles(): Article[] {
  const kw: string = this.keyword.trim().toLowerCase();
  return this.allArticles().filter((a: Article) => {
    const title: string = (a.title ?? '').toLowerCase();
    const summary: string = (a.summary ?? '').toLowerCase();
    const tag: string = (a.tag ?? '').toLowerCase();
    const author: string = (a.author ?? '').toLowerCase();
    return title.indexOf(kw) >= 0 || summary.indexOf(kw) >= 0
      || tag.indexOf(kw) >= 0 || author.indexOf(kw) >= 0;
  });
}

这段代码把“远程优先、本地补充”的策略说得很直白。先去重,再搜索,页面层就不需要到处判断数据来源。后续如果再增加赛事搜索或球员搜索,也可以沿用同一套思路继续扩展。

取舍分析

搜索页最常见的误区,是把“功能可用”等同于“标题可搜”。对于内容类应用来说,标题只是检索入口的一部分。摘要、标签、作者、品牌这些字段同样承载用户记忆,如果不纳入搜索范围,结果往往会显得过于稀疏。

另一个取舍在于远程数据的优先级。只看远程数据会丢掉本地兜底,只看本地数据又无法体现刷新后的新内容。羽球联盟把远程数据放在前面,再补上本地未覆盖项,实际上是在“内容新鲜度”和“内容完整度”之间找了一个更稳的平衡点。

设计落点

  • 搜索候选池应先完成合并与去重,再进入关键字过滤。
  • 资讯和装备各自维护命中逻辑,但页面交互保持一致。
  • 顶部统计、空态和结果列表一起构成完整搜索反馈。

易踩坑

  • 不要只搜标题,用户记住的往往是标签、作者、品牌或摘要关键词。
  • 远程和本地合并时如果不去重,刷新之后很容易出现重复卡片。
  • 空关键字和无结果要明确区分,否则用户很难判断是没搜还是没数据。

验证方式

  • 输入赛事或装备相关关键词,确认资讯 Tab 和装备 Tab 都能返回对应结果。
  • 输入不存在的词,确认页面给出明确空态而不是空白列表。
  • 清空关键字,确认页面回到提示态,而不是保留上一次结果。

参考资料

小结

第 12 篇真正想说明的,不是搜索框怎么摆,而是搜索结果如何在多数据源前提下依然保持清晰、稳定和可预期。先合并、再去重、最后过滤,这个顺序会直接决定搜索页是否可靠。

Logo

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

更多推荐