vue實(shí)現(xiàn)虛擬列表功能的代碼
當(dāng)數(shù)據(jù)量較大(此處設(shè)定為10w),而且要用列表的形式展現(xiàn)給用戶,如果我們不做處理的話,在瀏覽器中渲染10w dom節(jié)點(diǎn),是極其耗費(fèi)時(shí)間的,那我的Macbook air舉例,10w條數(shù)據(jù)渲染出來(lái)到能看到頁(yè)面,需要13秒多(實(shí)際應(yīng)該是10秒左右),如果是用戶的話肯定是不會(huì)等一個(gè)網(wǎng)頁(yè)十幾秒的
我們可以用虛擬列表解決這個(gè)問(wèn)題
一步步來(lái)
首先看一下效果
這是data中的數(shù)據(jù)
data() { return { list: [], // 賊大的數(shù)組 li: { // 列表項(xiàng)信息 height: 50, }, container: { // 容器信息 height: 500, }, pos: 1, // 第一排顯示的元素的下標(biāo) MAX_NUM: 1, // 在容器內(nèi)最多顯示幾個(gè)列表項(xiàng) timer: null, // 定時(shí)器 carriedOut: true, // 能不能執(zhí)行操作 }; },
然后在mounted中創(chuàng)建一個(gè)賊大的數(shù)組,在調(diào)用test方法計(jì)算第一次的虛擬列表中有哪些
mounted() { // 創(chuàng)建一個(gè)賊大的數(shù)據(jù)數(shù)組 for (let i = 0; i < 100000; i++) { this.list.push(i); } this.test(); },
test方法
test() { // 節(jié)流 if (this.carriedOut) { // 容器跟里面的列表項(xiàng) const { container, li } = this; // 計(jì)算可視區(qū)域最多能顯示多少個(gè)li this.MAX_NUM = Math.ceil(container.height / li.height); // 獲取 overflow:scroll 的元素已滾動(dòng)的高度 let scrollTop = this.$refs.container.scrollTop; // 計(jì)算當(dāng)前處于第一排的元素的下標(biāo) this.pos = Math.round(scrollTop / li.height); // 下方節(jié)流操作 this.carriedOut = false; this.timer = setTimeout(() => { this.carriedOut = true; clearTimeout(this.timer); }, 50); } },
然后是computed
computed: { // 用于渲染在頁(yè)面上的數(shù)組 showList() { // 根據(jù)計(jì)算出來(lái)的 第一排元素的下標(biāo),和最多顯示多少個(gè) 用slice實(shí)現(xiàn)截取數(shù)組 let arr = this.list.slice(this.pos, this.pos + this.MAX_NUM); return arr; }, },
這是html,注意監(jiān)聽(tīng)了div的scroll事件,并且調(diào)用的是test方法
<div class="virtual-list"> <h1>虛擬列表</h1> <div class="container" ref="container" :style="`height:${container.height}px`" @scroll="test"> <ul :style="`height:${li.height*list.length}px;padding-top:${li.height*pos}px`"> <li :style="`height:${li.height}px`" v-for="item in 100000" :key="item">{{item}}</li> </ul> </div> </div>
完整源代碼
<template> <div class="virtual-list"> <h1>虛擬列表</h1> <div class="container" ref="container" :style="`height:${container.height}px`" @scroll="test"> <ul :style="`height:${li.height*list.length}px;padding-top:${li.height*pos}px`"> <li :style="`height:${li.height}px`" v-for="item of showList" :key="item">{{item}}</li> </ul> </div> </div> </template> <script> export default { data() { return { list: [], // 賊大的數(shù)組 li: { // 列表項(xiàng)信息 height: 50, }, container: { // 容器信息 height: 500, }, pos: 1, // 第一排顯示的元素的下標(biāo) MAX_NUM: 1, // 在容器內(nèi)最多顯示幾個(gè)列表項(xiàng) timer: null, // 定時(shí)器 carriedOut: true, // 能不能執(zhí)行操作 }; }, mounted() { // 創(chuàng)建一個(gè)賊大的數(shù)據(jù)數(shù)組 for (let i = 0; i < 1000; i++) { this.list.push(i); } this.test(); }, computed: { // 用于渲染在頁(yè)面上的數(shù)組 showList() { // 根據(jù)計(jì)算出來(lái)的 第一排元素的下標(biāo),和最多顯示多少個(gè) 用slice實(shí)現(xiàn)截取數(shù)組 let arr = this.list.slice(this.pos, this.pos + this.MAX_NUM); return arr; }, }, methods: { test() { // 節(jié)流 if (this.carriedOut) { // 容器跟里面的列表項(xiàng) const { container, li } = this; // 計(jì)算可視區(qū)域最多能顯示多少個(gè)li this.MAX_NUM = Math.ceil(container.height / li.height); // 獲取 overflow:scroll 的元素已滾動(dòng)的高度 let scrollTop = this.$refs.container.scrollTop; // 計(jì)算當(dāng)前處于第一排的元素的下標(biāo) this.pos = Math.round(scrollTop / li.height); // 下方節(jié)流操作 this.carriedOut = false; this.timer = setTimeout(() => { this.carriedOut = true; clearTimeout(this.timer); }, 50); } }, }, }; </script> <style lang="scss" scoped> .virtual-list { text-align: center; .container { overflow: scroll; border: 1px solid red; } } </style>
到此這篇關(guān)于vue實(shí)現(xiàn)虛擬列表功能的代碼的文章就介紹到這了,更多相關(guān)vue 虛擬列表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue實(shí)現(xiàn)不定高虛擬列表的示例詳解
- 不同場(chǎng)景下Vue中虛擬列表實(shí)現(xiàn)
- 詳解vue3中虛擬列表組件的實(shí)現(xiàn)
- Vue中虛擬列表的原理與實(shí)現(xiàn)詳解
- 基于Vue實(shí)現(xiàn)封裝一個(gè)虛擬列表組件
- vue長(zhǎng)列表優(yōu)化之虛擬列表實(shí)現(xiàn)過(guò)程詳解
- 結(jié)合康熙選秀講解vue虛擬列表實(shí)現(xiàn)
- Vue 虛擬列表的實(shí)戰(zhàn)示例
- 使用 Vue 實(shí)現(xiàn)一個(gè)虛擬列表的方法
- vue簡(jiǎn)單實(shí)現(xiàn)一個(gè)虛擬列表的示例代碼
相關(guān)文章
微信小程序?qū)崙?zhàn)基于vue2實(shí)現(xiàn)瀑布流的代碼實(shí)例
瀑布流,又稱瀑布流式布局,是比較流行的一種網(wǎng)站頁(yè)面布局,視覺(jué)表現(xiàn)為參差不齊的多欄布局,隨著頁(yè)面滾動(dòng)條向下滾動(dòng),這種布局還會(huì)不斷加載數(shù)據(jù)塊并附加至當(dāng)前尾部,這篇文章主要介紹了微信小程序?qū)崙?zhàn),基于vue2實(shí)現(xiàn)瀑布流,需要的朋友可以參考下2022-12-12Vue項(xiàng)目保持element組件同行,設(shè)置組件不自動(dòng)換行問(wèn)題
這篇文章主要介紹了Vue項(xiàng)目保持element組件同行,設(shè)置組件不自動(dòng)換行問(wèn)題。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02Vue 基礎(chǔ)語(yǔ)法之計(jì)算屬性(computed)、偵聽(tīng)器(watch)、過(guò)濾器(filters)詳解
計(jì)算屬性就是 Vue 實(shí)例選項(xiàng)中的 computed,computed 的值是一個(gè)對(duì)象類型,對(duì)象中的屬性值為函數(shù),而且這個(gè)函數(shù)沒(méi)辦法接收參數(shù),這篇文章主要介紹了Vue 基礎(chǔ)語(yǔ)法之計(jì)算屬性(computed)、偵聽(tīng)器(watch)、過(guò)濾器(filters)詳解,需要的朋友可以參考下2022-11-11Nuxt.js之自動(dòng)路由原理的實(shí)現(xiàn)方法
這篇文章主要介紹了Nuxt.js之自動(dòng)路由原理的實(shí)現(xiàn)方法,nuxt.js會(huì)根據(jù)pages目錄結(jié)構(gòu)自動(dòng)生成vue-router模塊的路由配置。非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-11-11詳解Vue-cli中的靜態(tài)資源管理(src/assets和static/的區(qū)別)
這篇文章主要介紹了Vue-cli中的靜態(tài)資源管理(src/assets和static/的區(qū)別,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06Vue Element UI 表單自定義校驗(yàn)規(guī)則及使用
這篇文章主要介紹了Vue Element UI 表單自定義效驗(yàn)規(guī)則及使用,文中通過(guò)代碼介紹了常見(jiàn)表單效驗(yàn)規(guī)則,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02electron實(shí)現(xiàn)打印功能支持靜默打印、無(wú)感打印
使用electron開(kāi)發(fā)應(yīng)用遇到了打印小票的功能,實(shí)現(xiàn)途中還是幾經(jīng)波折,下面這篇文章主要給大家介紹了關(guān)于electron實(shí)現(xiàn)打印功能支持靜默打印、無(wú)感打印的相關(guān)資料,需要的朋友可以參考下2023-12-12一篇帶你搞懂Vue項(xiàng)目里的權(quán)限控制
這篇文章主要為大家介紹了vue項(xiàng)目里的權(quán)限控制,文中有詳細(xì)的代碼示例供大家參考,有需要的朋友可以借鑒參考下,希望能夠有所幫助2023-06-06Vue3-KeepAlive,多個(gè)頁(yè)面使用keepalive方式
這篇文章主要介紹了Vue3-KeepAlive,多個(gè)頁(yè)面使用keepalive方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08