Taro 小程序用展示组件解决解决重排问题

461 阅读3分钟

前言

在做一个业余项目(嗖嗖题),该项目有一个搜索列表需要升级。需要在列表中显示题干、选项以及答案与解析。若题干与选项超过5行,则隐藏超过5行部分的内容,并在右下角显示查看全部;答案与解析部分同理。技术栈是Taro,开发工具是百度小程序开发工具。

image.png

思路

第一反应是去找超过行数溢出隐藏的代码,比如CSS 控制多行文本展开收起,但该方案最终经过尝试后,发现无法实现 PRD 中的效果,对照需要实现的效果有两点限制:

  1. 题干与选项部分不是同一个组件,所以无法按照同一个组件中的内容设置相应 CSS 样式
  2. 无法控制“查看全部”按钮的显示隐藏

小伙伴有另一种思路 通过监听字数统计(中英文数字特殊符号等)判断总字数是否超过5行所能容纳的字数,不论该方案的复杂性(不是改改 CSS 样式就可以的),但该方案无法对比需要实现的效果有一点限制:

  1. 题干与选项是分开的组件,且各自都未必充满一行(即一行内会存在多余空格影响判断)。

最终的思路是通过渲染完组件后,设置对应内容(题干与选项、答案与解析)最大高度为5行,通过检查的高度是否超过5行来判断是否需要显示“展开全部”按钮。该方案:

  1. 能够判断是否应该显示隐藏
  2. 规避了空格部分对统计一行字数的误差

方案实现过程

刚开始的时候走了歧路,没有坚定执行展示组件(presentational components)单纯渲染数据的职责。

  1. testLists 列表(容器组件,字段如下图所示,包含 ids)循环渲染 TestDetailItem 组件

image.png image.png

  1. 每个 TestDetailItem 根据 ids 字段自己去分别请求选项和解析,请求完数据后填充进组件

image.png

  1. 通过异步测量内容组件的高度来判断“展开全部”按钮的显隐,答案与解析区域原理和题干与选项区域一致。

image.png image.png

这里的 API 用的是 TarocreateSelectorQuery。折腾了好久才弄出来,除了需要将选择器范围限制在该组件内(主要参考文档),还需要用 id 选择器而不是类选择器挂载(不然会出现编译完后找不到对应的类名)。

image.png

image.png

以上方案虽然通过定时器异步测量尺寸,但还是会存在部分请求的接口超时未反应,超过时限后数据进入导致列表重排,造成获取的尺寸不准确,如设置1秒后请求测量数据,但某列表项数据在2秒内返回数,于是该列表项通过尺寸测量 API 无法获取数据填充内容后的尺寸;测量尺寸定时器若设置太长时间,又会对用户的视觉效果造成影响。

image.png image.png

最终解决方案:

通过模拟数据验证后端直接返回填充内容的可行性后,提出方案。

image.png

修改后 TestDetailItem 就是一个展示组件,获取数据的操作全部由容器组件(container component)实现,成功实现效果。

image.png

后记

其实中间也有想过通过虚拟列表的方式避免不在视口的列表项渲染,但是需要升级 Taro3,但百度小程序的编译有问题,所以搁置了。 这个小小的搜索列表的功能,用到了重排、展示组件、容器组件等知识,还有各种查找文档踩坑,充实且有意义。

参考文档

标题
文章讲解录屏www.bilibili.com/video/BV14A…
CSS实现多行文本“展开收起”segmentfault.com/a/119000004…
多行内容超出...显示的终极方案juejin.cn/post/702665…

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情