虚拟列表在 Vue3 中的核心优势是仅渲染可视区域的内容,大幅提升大数据量列表的性能。以下是具体应用场景及实现方式:
vue-virtual-scroller 或自定义虚拟列表组件。<template>
<div class="container">
<VirtualTable :items="largeData" :itemHeight="36">
<template #item="{ item }">
<div class="table-row">
<div class="cell">{{ item.id }}</div>
<div class="cell">{{ item.name }}</div>
<div class="cell">{{ item.date }}</div>
</div>
</template>
</VirtualTable>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { VirtualTable } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
const largeData = ref(Array(10000).fill().map((\_, i) => ({
id: i + 1,
name: `用户${i + 1}`,
date: new Date().toISOString(),
})))
</script><template>
<div class="chat-container">
<ListScroller :items="messages" :itemSize="getItemSize">
<template #item="{ item }">
<MessageComponent :message="item" />
</template>
</ListScroller>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ListScroller } from 'vue-virtual-scroller'
import MessageComponent from './MessageComponent.vue'
const messages = ref(generateLargeMessages(5000)) // 生成5000条消息
const getItemSize = (item) => {
// 根据消息类型和内容动态计算高度
return item.isImage ? 200 : 50
}
</script>IntersectionObserver 预加载下一页数据。<template>
<div class="feed-container">
<VirtualList :items="posts" :itemHeight="300">
<template #item="{ item }">
<PostCard :post="item" />
</template>
</VirtualList>
<div v-if="loading" class="loading">加载中...</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { VirtualList } from 'vue-virtual-scroller'
import PostCard from './PostCard.vue'
const posts = ref([])
const loading = ref(false)
let page = 1
const loadMore = async () => {
if (loading.value) return
loading.value = true
const newPosts = await fetchPosts(page) // 模拟API请求
posts.value = [...posts.value, ...newPosts]
page++
loading.value = false
}
onMounted(() => {
loadMore()
})
</script><template>
<div class="reader-container">
<VirtualList :items="pages" :itemHeight="screenHeight">
<template #item="{ item }">
<PageContent :content="item.content" />
</template>
</VirtualList>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { VirtualList } from 'vue-virtual-scroller'
import PageContent from './PageContent.vue'
const screenHeight = computed(() => window.innerHeight - 100) // 减去导航栏高度
const pages = ref(generateBookPages(largeTextContent, screenHeight.value))
</script><template>
<div class="calendar-container">
<VirtualGrid
:rows="31"
:cols="7"
:cellHeight="80"
:cellWidth="100"
>
<template #cell="{ row, col }">
<CalendarCell :date="getDate(row, col)" />
</template>
</VirtualGrid>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { VirtualGrid } from 'vue-virtual-scroller'
import CalendarCell from './CalendarCell.vue'
</script><template>
<div class="tree-container">
<VirtualTree :nodes="fileTree">
<template #node="{ node, depth }">
<div :style="{ paddingLeft: `${depth \* 20}px` }">
<span>{{ node.name }}</span>
<button v-if="node.hasChildren" @click="loadChildren(node)">展开</button>
</div>
</template>
</VirtualTree>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { VirtualTree } from 'vue-virtual-scroller'
const fileTree = ref(generateInitialTree())
const loadChildren = async (node) => {
if (node.children) return
node.children = await fetchChildren(node.id) // 异步加载子节点
}
</script>useVirtualList 组合式函数,适合自定义实现。通过虚拟列表,即使处理百万级数据,也能保持流畅的滚动体验,大幅提升用户体验。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。