Vue NativeVue Native
Guide
Components
Composables
Navigation
  • iOS
  • Android
  • macOS
GitHub
Guide
Components
Composables
Navigation
  • iOS
  • Android
  • macOS
GitHub
  • Layout

    • VView
    • VScrollView
    • VSafeArea
    • VKeyboardAvoiding
  • Text & Input

    • VText
    • VInput
  • Interactive

    • VButton
    • VPressable
    • VSwitch
    • VSlider
    • VSegmentedControl
    • VCheckbox
    • VRadio
    • VDropdown
    • VRefreshControl
  • Media

    • VImage
    • VWebView
    • VVideo
  • Lists

    • VList
    • VFlatList
    • VSectionList
  • Feedback

    • VActivityIndicator
    • VProgressBar
    • VAlertDialog
    • VActionSheet
    • VModal
    • VErrorBoundary
  • Transition & State

    • VTransition & VTransitionGroup
    • KeepAlive
    • VSuspense
  • Navigation

    • VNavigationBar
    • VTabBar
  • System

    • VStatusBar
    • VPicker
  • macOS

    • VToolbar
    • VSplitView
    • VOutlineView

VList

A virtualized scrollable list backed by UITableView on iOS and RecyclerView on Android. Efficient for large datasets -- only visible rows are rendered.

Usage

VList uses a :data prop and an #item slot to render each row. Do not use v-for inside VList -- the native virtualization engine manages which rows are rendered.

<script setup>
import { ref } from '@thelacanians/vue-native-runtime'

const items = ref([
  { id: 1, title: 'Item 1' },
  { id: 2, title: 'Item 2' },
  { id: 3, title: 'Item 3' },
])
</script>

<template>
  <VList
    :data="items"
    :keyExtractor="item => item.id"
    :style="{ flex: 1 }"
  >
    <template #item="{ item }">
      <VView :style="{ padding: 16, borderBottomWidth: 1, borderBottomColor: '#eee' }">
        <VText>{{ item.title }}</VText>
      </VView>
    </template>
  </VList>
</template>

Props

PropTypeDefaultDescription
dataArrayrequiredThe array of items to render
keyExtractor(item: T, index: number) => stringindex as stringFunction that returns a unique key for each item
styleStyleProp--Container styles
estimatedItemHeightnumber44Estimated row height (improves scroll perf)
showsScrollIndicatorbooleantrueShow/hide the scroll bar
bouncesbooleantrueBounce at top/bottom (iOS only)
horizontalbooleanfalseRender the list horizontally

Slots

SlotPropsDescription
#item{ item, index }Render each list item. Required.
#header--Content rendered above the list items
#footer--Content rendered below the list items
#empty--Content shown when data is an empty array

Events

EventPayloadDescription
@scroll{ x: number, y: number }Fires as the user scrolls
@endReached--Fires when scrolled near the bottom (20% threshold). Use this for infinite scroll / pagination

Infinite scroll example

<script setup>
import { ref } from '@thelacanians/vue-native-runtime'

const items = ref(Array.from({ length: 20 }, (_, i) => ({ id: i + 1 })))
const loading = ref(false)

async function loadMore() {
  if (loading.value) return
  loading.value = true
  // fetch more items...
  loading.value = false
}
</script>

<template>
  <VList
    :data="items"
    :keyExtractor="item => item.id"
    :style="{ flex: 1 }"
    @endReached="loadMore"
  >
    <template #item="{ item }">
      <VView :style="{ padding: 16 }">
        <VText>Item {{ item.id }}</VText>
      </VView>
    </template>
    <template #footer>
      <VActivityIndicator v-if="loading" />
    </template>
  </VList>
</template>

Header, footer, and empty state

<template>
  <VList
    :data="items"
    :keyExtractor="item => item.id"
    :style="{ flex: 1 }"
  >
    <template #header>
      <VView :style="{ padding: 16 }">
        <VText :style="{ fontSize: 24, fontWeight: 'bold' }">My Items</VText>
      </VView>
    </template>

    <template #item="{ item }">
      <VView :style="{ padding: 16 }">
        <VText>{{ item.title }}</VText>
      </VView>
    </template>

    <template #empty>
      <VView :style="{ padding: 40, alignItems: 'center' }">
        <VText :style="{ color: '#999' }">No items yet</VText>
      </VView>
    </template>

    <template #footer>
      <VView :style="{ padding: 16, alignItems: 'center' }">
        <VText :style="{ color: '#999', fontSize: 12 }">End of list</VText>
      </VView>
    </template>
  </VList>
</template>

Performance

Set estimatedItemHeight close to your actual row height. This prevents layout jumps when the list first renders.

Edit this page
Last Updated: 2/28/26, 11:24 PM
Contributors: Abdul Hamid, Claude Opus 4.6
Next
VFlatList