vue3虚拟列表加载
- 第一步定义自己需要的展示的高度,以及每块item展示的内容
const msgData=[{
id:1,name:'2'}]
const itemHeight = 50
const visualHeight = 500
const rollHeight = itemHeight * msgData.length
const itemCount = Math.ceil(visualHeight / itemHeight)
const container = ref(null)
const start = ref(0)
const translateY = ref(0)
const dataList = computed(() => {
return msgData.slice(start.value, start.value + itemCount)
})
onMounted(() => {
container.value.addEventListener('scroll', e => {
const {
scrollTop } = e.target
start.value = Math.floor(scrollTop / itemHeight)
translateY.value = scrollTop + 'px'
})
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
* {
margin: 0;
}
.content {
overflow: auto;
display: flex;
}
</style>
</head>
<div id="app">
<div class="content" ref="container" :style="{ height: visualHeight }">
<div class="empty" :style="{ height: rollHeight }"></div>
<div class="list" :style="{ transform: `translateY(${translateY})`}">
<p v-for="item in dataList" :key="item" class="item" :style="{ height: itemHeight }">{
{
item.name }}</p>
</div>
</div>
</div>
<body>
<script>
const {
ref, onMounted, computed } = Vue
const App = {
setup() {
const msgData=[{
id:1,name:'1'},]
const itemHeight = 50
const visualHeight = 500
const rollHeight = itemHeight * msgData.length
const itemCount = Math.ceil(visualHeight / itemHeight)
const container = ref(null)
const start = ref(0)
const translateY = ref(0)
const dataList = computed(() => {
return msgData.slice(start.value, start.value + itemCount)
})
onMounted(() => {
container.value.addEventListener('scroll', e => {
const {
scrollTop } = e.target
start.value = Math.floor(scrollTop / itemHeight)
translateY.value = scrollTop + 'px'
})
})
return {
dataList,
container,
translateY,
visualHeight: `${
visualHeight}px`,
itemHeight: `${
itemHeight}px`,
rollHeight: `${
rollHeight}px`
}
}
}
Vue.createApp(App).mount('#app')
</script>
</body>
</html>