Skip to content

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 参考 ​

InfiniteScroll — 属性
名称类型默认值说明
distance
number | undefined
100
交叉观察器触发区域向视口外扩展的距离,单位为像素。
详情

声明类型

number | undefined

默认值详情

解析值
100

来源

InfiniteScroll.vue:9

packages/ui/src/components/infinite-scroll/InfiniteScroll.vue

delay
number | undefined
200
观察到加载哨兵后等待的防抖延迟,单位为毫秒。
详情

声明类型

number | undefined

默认值详情

解析值
200

来源

InfiniteScroll.vue:11

packages/ui/src/components/infinite-scroll/InfiniteScroll.vue

disabled
boolean | undefined
false
禁用加载检测并清理观察器;禁用期间不会触发加载。
详情

声明类型

boolean | undefined

字面量

  • false
  • true

默认值详情

解析值
false

来源

InfiniteScroll.vue:13

packages/ui/src/components/infinite-scroll/InfiniteScroll.vue

immediate
boolean | undefined
true
启用时在挂载或重新启用后立即请求一次加载;关闭后仅由哨兵进入扩展视口触发。
详情

声明类型

boolean | undefined

字面量

  • false
  • true

默认值详情

解析值
true

来源

InfiniteScroll.vue:15

packages/ui/src/components/infinite-scroll/InfiniteScroll.vue

class
string | undefined
undefined
追加到列表、加载状态和观察哨兵共同外层容器的 CSS 类。
详情

声明类型

string | undefined

默认值详情

解析值
undefined

来源

InfiniteScroll.vue:16

packages/ui/src/components/infinite-scroll/InfiniteScroll.vue

InfiniteScroll — 事件
名称签名或类型说明
@load
[]
防抖延迟结束后需要加载更多数据时发出,不带参数;父组件完成加载后应调用 resetLoading()。
详情

声明类型

[]

来源

InfiniteScroll.vue

packages/ui/src/components/infinite-scroll/InfiniteScroll.vue

InfiniteScroll — 插槽
名称签名或类型说明
#default
{}
要持续追加的列表或滚动内容。
详情

声明类型

{}

来源

InfiniteScroll.vue

packages/ui/src/components/infinite-scroll/InfiniteScroll.vue

#loading
{}
加载请求进行时显示的自定义指示器;未提供时显示脉冲圆点。
详情

声明类型

{}

来源

InfiniteScroll.vue

packages/ui/src/components/infinite-scroll/InfiniteScroll.vue

InfiniteScroll — 暴露成员
名称签名或类型说明
resetLoading
() => void
标记加载完成并重新检查哨兵;若哨兵仍在扩展视口内可能立即再次发出 load,无更多数据时应先将 disabled 设为 true。
详情

声明类型

() => void

来源

InfiniteScroll.vue:184

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 选项 ​

选项类型默认值说明
distancenumber100触发距离阈值(像素)
delaynumber200防抖延迟(毫秒)
disabledbooleanfalse是否禁用
immediatebooleantrue挂载时是否立即检查
onLoad() => void—(必填)加载回调

useInfiniteScroll 返回值 ​

属性类型说明
isLoadingRef<boolean>是否正在加载
resetLoading() => void重置加载状态

可访问性 ​

  • 屏幕阅读器:加载状态会被播报
  • 减少动效:加载动画尊重 prefers-reduced-motion 设置

蛮力铸就。