InfiniteScroll 无限滚动
滚动到底部自动加载更多数据。使用 IntersectionObserver 实现高效的滚动检测。
预览
Preview
已加载:10 / 25
数据项 1
数据项 2
数据项 3
数据项 4
数据项 5
数据项 6
数据项 7
数据项 8
数据项 9
数据项 10
安装
pnpm dlx brutx-vue@latest add infinite-scroll用法
vue
<script setup>
import { ref } from 'vue'
import { InfiniteScroll } from 'brutx-ui-vue'
const items = ref(Array.from({ length: 20 }, (_, i) => `项目 ${i + 1}`))
const loading = ref(false)
async function loadMore() {
loading.value = true
// 模拟 API 调用
await new Promise(resolve => setTimeout(resolve, 1000))
const newItems = Array.from(
{ length: 10 },
(_, i) => `项目 ${items.value.length + i + 1}`
)
items.value.push(...newItems)
loading.value = false
}
</script>
<template>
<InfiniteScroll @load="loadMore">
<div v-for="item in items" :key="item" class="p-4 border-b">
{{ item }}
</div>
</InfiniteScroll>
</template>自定义加载状态
vue
<script setup>
import { ref } from 'vue'
import { InfiniteScroll, Spinner } from 'brutx-ui-vue'
const items = ref([])
async function loadMore() {
// 加载数据
}
</script>
<template>
<InfiniteScroll @load="loadMore">
<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>
<template #loading>
<div class="flex items-center justify-center py-4">
<Spinner size="sm" />
<span class="ml-2">加载中...</span>
</div>
</template>
</InfiniteScroll>
</template>禁用状态
vue
<script setup>
import { ref } from 'vue'
import { InfiniteScroll } from 'brutx-ui-vue'
const items = ref([])
const hasMore = ref(true)
async function loadMore() {
if (!hasMore.value) return
// 加载数据...
// 如果没有更多数据:
// hasMore.value = false
}
</script>
<template>
<InfiniteScroll :disabled="!hasMore" @load="loadMore">
<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>
</InfiniteScroll>
</template>API 参考
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
distance | number | undefined | 100 | 交叉观察器触发区域向视口外扩展的距离,单位为像素。 |
详情声明类型number | undefined 默认值详情
来源packages/ui/src/components/infinite-scroll/InfiniteScroll.vue | |||
delay | number | undefined | 200 | 观察到加载哨兵后等待的防抖延迟,单位为毫秒。 |
详情声明类型number | undefined 默认值详情
来源packages/ui/src/components/infinite-scroll/InfiniteScroll.vue | |||
disabled | boolean | undefined | false | 禁用加载检测并清理观察器;禁用期间不会触发加载。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/infinite-scroll/InfiniteScroll.vue | |||
immediate | boolean | undefined | true | 启用时在挂载或重新启用后立即请求一次加载;关闭后仅由哨兵进入扩展视口触发。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/infinite-scroll/InfiniteScroll.vue | |||
class | string | undefined | undefined | 追加到列表、加载状态和观察哨兵共同外层容器的 CSS 类。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/infinite-scroll/InfiniteScroll.vue | |||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
@load | [] | 防抖延迟结束后需要加载更多数据时发出,不带参数;父组件完成加载后应调用 resetLoading()。 |
详情声明类型[] 来源packages/ui/src/components/infinite-scroll/InfiniteScroll.vue | ||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
#default | {} | 要持续追加的列表或滚动内容。 |
详情声明类型{}来源packages/ui/src/components/infinite-scroll/InfiniteScroll.vue | ||
#loading | {} | 加载请求进行时显示的自定义指示器;未提供时显示脉冲圆点。 |
详情声明类型{}来源packages/ui/src/components/infinite-scroll/InfiniteScroll.vue | ||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
resetLoading | () => void | 标记加载完成并重新检查哨兵;若哨兵仍在扩展视口内可能立即再次发出 load,无更多数据时应先将 disabled 设为 true。 |
详情声明类型() => void 来源packages/ui/src/components/infinite-scroll/InfiniteScroll.vue | ||
组合式函数
更灵活的用法,使用 useInfiniteScroll 组合式函数:
vue
<script setup>
import { ref } from 'vue'
import { useInfiniteScroll } from 'brutx-ui-vue'
const containerRef = ref(null)
const items = ref([])
const { isLoading, resetLoading } = useInfiniteScroll(containerRef, {
distance: 100,
delay: 200,
onLoad: async () => {
// 加载数据
const newItems = await fetchItems()
items.value.push(...newItems)
resetLoading()
},
})
</script>
<template>
<div ref="containerRef">
<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>
</div>
</template>useInfiniteScroll 选项
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
distance | number | 100 | 触发距离阈值(像素) |
delay | number | 200 | 防抖延迟(毫秒) |
disabled | boolean | false | 是否禁用 |
immediate | boolean | true | 挂载时是否立即检查 |
onLoad | () => void | —(必填) | 加载回调 |
useInfiniteScroll 返回值
| 属性 | 类型 | 说明 |
|---|---|---|
isLoading | Ref<boolean> | 是否正在加载 |
resetLoading | () => void | 重置加载状态 |
可访问性
- 屏幕阅读器:加载状态会被播报
- 减少动效:加载动画尊重
prefers-reduced-motion设置