Skip to content
Back to skills

N Infinite Scroll

ASecurity

Infinite scroll component for loading content on scroll. Invoke when user needs to implement infinite scrolling lists or lazy loading content in Naive UI.

  • 8 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added September 11, 2026
developmentjavascriptjavavueapi

Works with

  • api

Security analysis

A100/100

Scanned September 11, 2026

npx -y skills add jiaiyan/naive-ui-skills --skill n-infinite-scroll --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of N Infinite Scroll?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for N Infinite Scroll
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jiaiyan-n-infinite-scroll/badge)](https://www.skillsdirectory.com/skills/jiaiyan-n-infinite-scroll)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: "n-infinite-scroll"
description: "Infinite scroll component for loading content on scroll. Invoke when user needs to implement infinite scrolling lists or lazy loading content in Naive UI."
metadata:
  author: jiaiyan
  version: "1.0.0"
---

# Naive UI Infinite Scroll Component

Infinite scroll component for implementing endless scrolling lists with automatic content loading.

## When to Use

Use this component when:
- **Infinite lists**: Load more content as user scrolls
- **Lazy loading**: Implement progressive content loading
- **Chat interfaces**: Display message history with auto-loading
- **Feed layouts**: Social media style content feeds

## When to Invoke

Invoke this skill when:
- User needs to implement infinite scrolling
- User wants to load content progressively on scroll
- User needs to detect when user reaches bottom of container
- User asks about implementing lazy loading lists

## Features

- **Auto Loading**: Automatically triggers load when near bottom
- **Custom Distance**: Configurable distance threshold for loading
- **Scrollbar Integration**: Works with Naive UI Scrollbar
- **Loading States**: Support for loading indicators
- **End Detection**: Handle end of data gracefully

## API Reference

### Infinite Scroll Props

| Name | Type | Default | Description |
|------|------|---------|-------------|
| distance | `number` | `0` | Distance threshold that triggers loading. |
| scrollbar-props | `Object` | `undefined` | Props for the internal Scrollbar component. |

### Infinite Scroll Events

| Name | Type | Description |
|------|------|-------------|
| on-load | `() => Promise<void> \| void` | Callback when scrolling near bottom. |

## Basic Usage

### Basic Infinite Scroll

```vue
<template>
  <n-infinite-scroll style="height: 240px" :distance="10" @load="handleLoad">
    <div v-for="i in count" :key="i" class="item">
      {{ i }}
    </div>
  </n-infinite-scroll>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(10)

const handleLoad = async () => {
  await new Promise(resolve => setTimeout(resolve, 1000))
  count.value += 10
}
</script>

<style scoped>
.item {
  display: flex;
  align-items: center;
  height: 46px;
  justify-content: center;
  margin-bottom: 10px;
  background-color: rgba(0, 128, 0, 0.16);
}
</style>
```

### With Loading and End States

```vue
<template>
  <n-infinite-scroll style="height: 240px" :distance="10" @load="handleLoad">
    <div v-for="(item, index) in items" :key="item.key" class="message">
      {{ item.content }}
    </div>
    <div v-if="loading" class="text">
      Loading...
    </div>
    <div v-if="noMore" class="text">
      No More Data
    </div>
  </n-infinite-scroll>
</template>

<script setup>
import { ref } from 'vue'

const items = ref([])
const loading = ref(false)
const noMore = ref(false)
let page = 1

const handleLoad = async () => {
  if (loading.value || noMore.value) return
  
  loading.value = true
  const newItems = await fetchData(page)
  
  if (newItems.length === 0) {
    noMore.value = true
  } else {
    items.value.push(...newItems)
    page++
  }
  
  loading.value = false
}
</script>
```

## Common Patterns

### Chat Messages

```vue
<template>
  <n-infinite-scroll style="height: 400px" :distance="10" @load="loadMessages">
    <div
      v-for="(message, index) in messages"
      :key="message.id"
      class="message"
      :class="{ reverse: message.isMine }"
    >
      <img class="avatar" :src="message.avatar" alt="">
      <span>{{ message.content }}</span>
    </div>
    <div v-if="loading" class="text">
      Loading messages...
    </div>
    <div v-if="noMoreMessages" class="text">
      No more messages
    </div>
  </n-infinite-scroll>
</template>

<script setup>
import { ref } from 'vue'

const messages = ref([])
const loading = ref(false)
const noMoreMessages = ref(false)

const loadMessages = async () => {
  if (loading.value || noMoreMessages.value) return
  
  loading.value = true
  const olderMessages = await fetchOlderMessages()
  
  if (olderMessages.length === 0) {
    noMoreMessages.value = true
  } else {
    messages.value = [...olderMessages, ...messages.value]
  }
  
  loading.value = false
}
</script>

<style scoped>
.message {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  padding: 10px;
}

.reverse {
  flex-direction: row-reverse;
}

.avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  margin: 0 10px;
}

.text {
  text-align: center;
  padding: 10px;
}
</style>
```

### With Custom Scrollbar

```vue
<template>
  <n-infinite-scroll
    style="height: 300px"
    :distance="20"
    :scrollbar-props="{ trigger: 'hover', size: 8 }"
    @load="handleLoad"
  >
    <n-list bordered>
      <n-list-item v-for="item in items" :key="item.id">
        {{ item.title }}
      </n-list-item>
    </n-list>
  </n-infinite-scroll>
</template>

<script setup>
import { ref } from 'vue'

const items = ref([])

const handleLoad = async () => {
  const newItems = await fetchMoreItems()
  items.value.push(...newItems)
}
</script>
```

### Feed with Cards

```vue
<template>
  <n-infinite-scroll style="height: 600px" :distance="50" @load="loadMore">
    <n-space vertical :size="16">
      <n-card v-for="post in posts" :key="post.id" :title="post.title">
        {{ post.content }}
      </n-card>
    </n-space>
    <template v-if="loading">
      <n-spin size="medium" />
    </template>
  </n-infinite-scroll>
</template>

<script setup>
import { ref } from 'vue'

const posts = ref([])
const loading = ref(false)
let page = 1

const loadMore = async () => {
  loading.value = true
  const newPosts = await fetchPosts(page)
  posts.value.push(...newPosts)
  page++
  loading.value = false
}
</script>
```

### Data Table with Infinite Scroll

```vue
<template>
  <n-infinite-scroll style="height: 400px" @load="loadMoreRows">
    <n-data-table :columns="columns" :data="tableData" />
  </n-infinite-scroll>
</template>

<script setup>
import { ref } from 'vue'

const columns = [
  { title: 'Name', key: 'name' },
  { title: 'Age', key: 'age' },
  { title: 'Address', key: 'address' }
]

const tableData = ref([])

const loadMoreRows = async () => {
  const newRows = await fetchMoreData()
  tableData.value.push(...newRows)
}
</script>
```

## Best Practices

1. **Set explicit height**: Always set a fixed height on the scroll container
   ```vue
   <n-infinite-scroll style="height: 400px" @load="handleLoad">
   ```

2. **Handle loading state**: Prevent multiple simultaneous load calls
   ```javascript
   const handleLoad = async () => {
     if (loading.value) return
     loading.value = true
     // ... load data
     loading.value = false
   }
   ```

3. **Implement end detection**: Show users when all data is loaded
   ```vue
   <div v-if="noMore">No more data</div>
   ```

4. **Use appropriate distance**: Adjust distance based on item size
   ```vue
   <n-infinite-scroll :distance="50" /> <!-- Larger items -->
   <n-infinite-scroll :distance="10" /> <!-- Smaller items -->
   ```

5. **Add loading indicators**: Provide visual feedback during loading
   ```vue
   <n-spin v-if="loading" />
   ```

6. **Handle errors gracefully**: Implement error handling for failed loads
   ```javascript
   const handleLoad = async () => {
     try {
       const data = await fetchData()
       items.value.push(...data)
     } catch (error) {
       message.error('Failed to load data')
     }
   }
   ```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.