作用域插槽配合v-for不是用于嵌套循环,而是让父组件自主控制列表每项渲染逻辑;子组件仅提供数据与状态,通过作用域插槽传递item、index、isLoading等,结合虚拟滚动只渲染可视区域,提升无限滚动性能。

作用域插槽配合 v-for 不是用来“嵌套循环”的,而是让列表每一项的渲染逻辑由父组件自主控制——子组件只管提供数据和状态,父组件决定怎么画、何时画、画成什么样。这种分工正是实现高性能无限滚动的关键基础。
用作用域插槽把每项数据“托付”给父组件
子组件(如 <infinite-list></infinite-list>)内部用 v-for 遍历数据,但不直接写 DOM 模板;而是通过作用域插槽把当前项(item)、索引(index)、甚至加载状态(isLoading)一并传出去:
子组件模板示例:
这样,父组件就能用 v-slot="{ item, index }" 接收,并自由定制每个条目的结构、样式、甚至是否启用骨架屏或懒加载图片。
结合虚拟滚动,只渲染可视区域
真正提升性能的不是插槽本身,而是它与虚拟滚动逻辑的协同:
- 子组件内部维护
visibleItems—— 仅包含当前滚动视口内需要渲染的那几项(比如 10~15 条),而非全部几千条 -
v-for只作用于这个精简数组,DOM 节点数量恒定,滚动不卡顿 - 作用域插槽让父组件能为这少量条目注入完整交互能力:点击跳转、长按菜单、动态图标状态等,不影响性能
Footer 加载提示也走作用域插槽
无限滚动的底部状态(加载中 / 失败 / 到底了)不应硬编码在子组件里,而应统一通过具名作用域插槽暴露:
子组件预留:
父组件使用时可精准响应:
- 当
loading为 true:显示带旋转动画的「加载中…」,并禁用重复触发 - 当
error存在:显示错误文案 + 「重试」按钮,点击调用子组件暴露的retry()方法 - 当
reached-end为 true:淡入「没有更多了」,避免突兀消失
滚动监听交给 IntersectionObserver,不卡主线程
不要在 @scroll 中反复计算位置。子组件内部用 IntersectionObserver 监听页脚元素是否进入视口:
- 监听目标是 footer 插槽渲染出的真实 DOM 元素
- 一旦进入阈值范围(如距离底部 200px),触发
loadMore() - 该机制天然防抖、低耗、兼容性好,比
window.onscroll更适合无限滚动场景


















