Spots

小程序点餐页吸顶滚动之分类按需加载,上划切换

点餐页常见的做法是先请求分类,再把所有分类的商品一起取回来,右侧排成一条长列表。这样做左右联动很直观:滚到哪一段,就选中左边哪一类。但商超分类多、商品数量差异又大时,用户可能只看了前两类,后面十几类的商品却已经全部请求并渲染了。 这次想试的是另一种节奏:分类目录先展示,右侧一次只看一个分类;进入某一类时才加载它的商品。少的分类只有一两件,多的分类可以有十几件。滑到当前分类底部,会看到“上拉继续浏览下一类”;再次上拉,或者直接点击提示,才进入下一类。 实现时,页面保留一个主要的纵向滚动容器,左侧分类栏吸顶并可独立滚动。右侧只渲染当前分类,重点是把商品请求放到真正进入分类的时刻。

页面一开始就知道分类的顺序、名称和下一类是谁,但不因此生成所有商品。Demo 用本地 categories 模拟分类目录,用…

页面一开始就知道分类的顺序、名称和下一类是谁,但不因此生成所有商品。Demo 用本地 categories 模拟分类目录,用 fetchCategoryDishes(category) 模拟按分类 ID 请求商品。makeDishes 在这次模拟请求执行时才生成该分类的商品,进入页面只加载第一类。 这里的商品数量只是 mock 配置,用来展示两件、九件、一件、十二件以及空分类等不同高度。真实接口接入时,应让分类接口返回目录,再按当前分类 ID 请求商品;不要把 Demo 的 count 当作实际商品列表。 点击左侧分类、点击底部提示、上拉进入下一类,最终都走分类切换逻辑。它先更新左侧高亮和右侧分类信息,再把外层滚动位置移回菜单顶部,最后加载目标分类。已访问过的分类直接从 productCache 恢复,不再发同一请求。 因此这不是“把下一类追加到当前列表底下”的无限列表。切换后右侧只有目标分类,向前查看可以点左侧分类,已请求的数据仍在本页缓存中。Demo 顶部的“请求次数 / 缓存类数”就是为了直观看出这点。

模拟请求也有两个容易忽略的保护:pendingRequests 按分类 ID 复用尚未结束的 Promise,避免快速重复操作发出同一请求;请求回来后只有目标分…

模拟请求也有两个容易忽略的保护:pendingRequests 按分类 ID 复用尚未结束的 Promise,避免快速重复操作发出同一请求;请求回来后只有目标分类仍是当前分类,才把结果显示到右侧。快速从 A 切到 B 时,A 的迟到响应可以入缓存,但不能覆盖 B 的页面。

如果一滚到底就立刻请求下一类,短分类会尤其容易被跳过。这个 Demo 把“到达底部”和“确认继续”拆成两次动作:滚动事件和 scrolltolower…

如果一滚到底就立刻请求下一类,短分类会尤其容易被跳过。这个 Demo 把“到达底部”和“确认继续”拆成两次动作:滚动事件和 scrolltolower 更新底部状态;手指按下时记录本次手势开始前是否已经到底;抬起时还在底部、且向上滑过一定距离,才切换下一类。 触摸事件只绑在右侧商品区域,滚动左侧分类栏不会误触发“下一类”。不想再滑一次时,next-cue 本身也可以点击。最后一个分类只显示“已浏览全部分类”,不会继续请求不存在的分类。 一两件商品的分类还有一个布局问题:右侧内容太短,左侧 position: sticky 所在的父容器如果也只有一小段高度,左栏还没来得及贴住固定头部,整个菜单就滚走了。固定的 demo-hero 随后会盖住分类。 所以需要量出 demo-hero 的实际高度,再分别计算滚动内容的顶部留白和左栏的吸顶位置。菜单区域至少占满一屏,让短商品列表也有足够的吸顶行程。 页面只有一个主要的纵向 scroll-view,左侧分类栏才有自己的内部滚动。切换分类后,scrollToMenu 用菜单相对于滚动内容的位置减去固定头部高度,让右侧从菜单顶部开始展示,不把分类标题藏到 demo-hero 后面。 按需加载不能只处理“有商品”的成功状态。Demo 分别展示加载中、零商品和加载失败;顶部“模拟失败”会让下一次未缓存分类的模拟请求失败,右侧可点击“重新加载”。缓存中即使是空数组,也代表该分类已经成功请求过,不应反复请求。

目前的 fetchCategoryDishes 只是延时 mock,没有接真实接口,也没有做单分类分页。如果真实分类内部还有多页商品,应该先把该分类的页加载到结…

目前的 fetchCategoryDishes 只是延时 mock,没有接真实接口,也没有做单分类分页。如果真实分类内部还有多页商品,应该先把该分类的页加载到结束,再允许底部提示进入下一分类;否则“上拉下一类”会抢走“加载当前类下一页”的手势。

代码在 menu-scroll-on-demand.vue,微信小程序页面路由为 /pages-demo/menu-scroll-on-demand。依次看两件…

代码在 menu-scroll-on-demand.vue,微信小程序页面路由为 /pages-demo/menu-scroll-on-demand。依次看两件商品的短分类、九件商品的长分类、零商品分类,再返回已经访问过的分类,可以观察滚动边界、请求计数与缓存行为。 这套方式适合“用户一次专注一类,按需进入下一类”的商超菜单。分类目录保持完整,商品请求则跟随用户的选择推进,页面不必为尚未浏览的分类提前承担加载和渲染成本。

News

小程序点餐页吸顶滚动之分类按需加载,上划切换

点餐页常见的做法是先请求分类,再把所有分类的商品一起取回来,右侧排成一条长列表。这样做左右联动很直观:滚到哪一段,就选中左边哪一类。但商超分类多、商品数量差异又大时,用户可能只看了前两类,后面十几类的商品却已经全部请求并渲染了。 这次想试的是另一种节奏:分类目录先展示,右侧一次只看一个分类;进入某一类时才加载它的商品。少的分类只有一两件,多的分类可以有十几件。滑到当前分类底部,会看到“上拉继续浏览…

@spots
Source: Juejin
See more like this