您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“vue虛擬列表如何實(shí)現(xiàn)”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
現(xiàn)在解決多數(shù)據(jù)渲染,相信大家可能會想到分頁,觸底加載,懶加載等等,但其實(shí)虛擬列表也是多數(shù)據(jù)高性能加載的一個重要解決方案。
虛擬滾動,就是根據(jù)容器可視區(qū)域的列表容積數(shù)量,監(jiān)聽用戶滑動或滾動事件,動態(tài)截取長列表數(shù)據(jù)中的部分?jǐn)?shù)據(jù)渲染到頁面上,動態(tài)使用空白站位填充容器上下滾動區(qū)域內(nèi)容,模擬實(shí)現(xiàn)原生滾動效果
瀏覽器渲染===康熙選秀:一次性渲染10000個肯定會使瀏覽器壓力大,造成用戶體驗(yàn)差
容器可視區(qū)域===選秀大殿:10000個排隊(duì)去渲染,比如一次渲染10個
上方下方區(qū)域===左右偏殿:輪不到你渲染,你就乖乖進(jìn)空白區(qū)待著
可視區(qū)域的高度
列表項(xiàng)的高度
可視區(qū)域能展示的列表項(xiàng)個數(shù) = ~~(可視區(qū)域高度 / 列表項(xiàng)高度) + 2
開始索引
結(jié)束索引
預(yù)加載(防止?jié)L動過快,造成暫時白屏)
根據(jù)開始索引和結(jié)束索引,截取數(shù)據(jù)展示在可視區(qū)域
滾動節(jié)流
上下空白區(qū)使用padding實(shí)現(xiàn)
滑動到底,再次請求數(shù)據(jù)并拼接
<template> <div @scroll.passive="doScroll" ref="scrollBox"> <div : > <div v-for="item in tempSanxins" :key="item.id"> <span>{{ item.msg }}</span> <img :src="item.src" /> </div> </div> </div> </template> <script> import { throttle } from "../../utils/tools"; export default { data() { return { allSanxins: [], // 所有數(shù)據(jù) itemHiehgt: 150, // 列表每一項(xiàng)的寬度 boxHeight: 0, // 可視區(qū)域的高度 startIndex: 0, // 元素開始索引 }; }, created() { // 模擬請求數(shù)據(jù) this.getAllSanxin(30); }, mounted() { // 在mounted時獲取可視區(qū)域的高度 this.getScrollBoxHeight(); // 監(jiān)聽屏幕變化以及旋轉(zhuǎn),都要重新獲取可視區(qū)域的高度 window.onresize = this.getScrollBoxHeight; window.onorientationchange = this.getScrollBoxHeight; }, methods: { getAllSanxin(count) { // 模擬獲取數(shù)據(jù) const length = this.allSanxins.length; for (let i = 0; i < count; i++) { this.allSanxins.push({ id: `sanxin${length + i}`, msg: `我是三心${length + i}號`, // 這里隨便選一張圖片就行 src: require("../../src/asset/images/sanxin.jpg").default, }); } }, // 使用節(jié)流,提高性能 doScroll: throttle(function () { // 監(jiān)聽可視區(qū)域的滾動事件 // 公式:~~(滾動的距離 / 列表項(xiàng) ),就能算出已經(jīng)滾過了多少個列表項(xiàng),也就能知道現(xiàn)在的startIndex是多少 // 例如我滾動條滾過了160px,那么index就是1,因?yàn)榇藭r第一個列表項(xiàng)已經(jīng)被滾上去了,可視區(qū)域里的第一項(xiàng)的索引是1 const index = ~~(this.$refs.scrollBox.scrollTop / this.itemHiehgt); if (index === this.startIndex) return; this.startIndex = index; if (this.startIndex + this.itemNum > this.allSanxins.length - 1) { this.getAllSanxin(30); } }, 200), getScrollBoxHeight() { // 獲取可視區(qū)域的高度 this.boxHeight = this.$refs.scrollBox.clientHeight; }, }, computed: { itemNum() { // 可視區(qū)域可展示多少個列表項(xiàng)? 計算公式:~~(可視化區(qū)域高度 / 列表項(xiàng)高度) + 2 // ~~是向下取整的運(yùn)算符,等同于Math.floor(),為什么要 +2 ,是因?yàn)榭赡茏钌厦婧妥钕旅娴脑囟贾徽故疽徊糠? return ~~(this.boxHeight / this.itemHiehgt) + 2; }, endIndex() { // endIndex的計算公式:(開始索引 + 可視區(qū)域可展示多少個列表項(xiàng) * 2) // 比如可視區(qū)域可展示8個列表項(xiàng),startIndex是0的話endIndex就是0 + 8 * 2 = 16,startIndex是1的話endIndex就是1 + 8 * 2 = 17,以此類推 // 為什么要乘2呢,因?yàn)檫@樣的話可以預(yù)加載出一頁的數(shù)據(jù),防止?jié)L動過快,出現(xiàn)暫時白屏現(xiàn)象 let index = this.startIndex + this.itemNum * 2; if (!this.allSanxins[index]) { // 到底的情況,比如startIndex是99995,那么endIndex本應(yīng)該是99995 + 8 * 2 = 10011 // 但是列表數(shù)據(jù)總數(shù)只有10000條,此時就需要讓endIndex = (列表數(shù)據(jù)長度 - 1) index = this.allSanxins.length - 1; } return index; }, tempSanxins() { // 可視區(qū)域展示的截取數(shù)據(jù),使用了數(shù)組的slice方法,不改變原數(shù)組又能截取 let startIndex = 0; if (this.startIndex <= this.itemNum) { startIndex = 0; } else { startIndex = this.startIndex + this.itemNum; } return this.allSanxins.slice(startIndex, this.endIndex + 1); }, blankStyle() { // 上下方的空白處使用padding來充當(dāng) let startIndex = 0; if (this.startIndex <= this.itemNum) { startIndex = 0; } else { startIndex = this.startIndex - this.itemNum; } return { // 上方空白的高度計算公式:(開始index * 列表項(xiàng)高度) // 比如你滾過了3個列表項(xiàng),那么上方空白區(qū)高度就是3 * 150 = 450,這樣才能假裝10000個數(shù)據(jù)的滾動狀態(tài) paddingTop: startIndex * this.itemHiehgt + "px", // 下方空白的高度計算公式:(總數(shù)據(jù)的個數(shù) - 結(jié)束index - 1) * 列表項(xiàng)高度 // 例如現(xiàn)在結(jié)束index是100,那么下方空白高度就是:(10000 - 100 - 1) * 150 = 1,484,850 paddingBottom: (this.allSanxins.length - this.endIndex - 1) * this.itemHiehgt + "px", // 不要忘了加px哦 }; }, }, }; </script> <style scoped> .v-scroll { height: 100%; /* padding-bottom: 500px; */ overflow: auto; .scroll-item { height: 148px; /* width: 100%; */ border: 1px solid black; display: flex; justify-content: space-between; align-items: center; padding: 0 20px; img { height: 100%; } } } </style>
“vue虛擬列表如何實(shí)現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。