亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Vue如何手寫一個(gè)虛擬列表

 更新時(shí)間:2024年04月19日 10:22:03   作者:吃肉不吃皮  
虛擬列表是一種優(yōu)化長(zhǎng)列表渲染的技術(shù),它可以在保持流暢性的同時(shí),渲染大量的數(shù)據(jù),本文主要介紹了如何使用vue手寫一個(gè)虛擬列表,感興趣的可以了解下

前言

何為虛擬列表?

回答這個(gè)問題先想一下,對(duì)于返回的幾千上萬條列表數(shù)據(jù),作為前端會(huì)如何渲染?

分頁唄,最開始想到的就是分頁。但是,萬一接口沒做分頁呢?好,就算后端做分頁了,那么用戶在瀏覽到第幾千條、第幾萬條數(shù)據(jù)時(shí)前端難道要把這第幾千條、幾萬條的DOM都渲染出來嗎?顯然是很消耗性能的(畢竟如此多的DOM,而且每個(gè)DOM內(nèi)部都有其他樣式細(xì)節(jié))如何優(yōu)化?此時(shí)就可以用到虛擬列表了

虛擬列表是一種優(yōu)化長(zhǎng)列表渲染的技術(shù),它可以在保持流暢性的同時(shí),渲染大量的數(shù)據(jù)。

在傳統(tǒng)的列表渲染中,如果列表非常長(zhǎng),會(huì)導(dǎo)致渲染時(shí)間過長(zhǎng)(前面所說的會(huì)有幾千幾萬個(gè)DOM),頁面卡頓,用戶體驗(yàn)變得非常差。而虛擬列表則是只渲染可見區(qū)域內(nèi)的數(shù)據(jù),而非全部渲染,這樣就可以大大提高渲染效率,保持頁面流暢性

常見場(chǎng)景

商品列表、社交列表...(暫時(shí)想到這兩個(gè))

手寫虛擬列表

進(jìn)行虛擬列表的實(shí)現(xiàn)之前先搞清楚一個(gè)問題:

是什么造成了這么多數(shù)據(jù)在渲染時(shí)產(chǎn)生卡頓?是數(shù)據(jù)數(shù)量太多引起的嗎?

準(zhǔn)確來說,應(yīng)該是是由于要渲染的DOM太多造成的卡頓。數(shù)據(jù)本身只是數(shù)據(jù),對(duì)于拿到的幾千上萬條數(shù)據(jù)它本身的大小對(duì)于內(nèi)存來說只能說是冰山一角吧

虛擬列表的原理

數(shù)據(jù)我還是這么多數(shù)據(jù),但是我不一次性渲染這么多數(shù)據(jù),我只渲染其中的一小部分(比如十條),這樣當(dāng)用戶滾動(dòng)的時(shí)候就重復(fù)變化這一小部分的DOM的渲染效果。這樣就能從原先幾千上萬個(gè)DOM變成現(xiàn)在的十個(gè),減少了一個(gè)量級(jí),減輕了渲染的壓力。而這一小部分顯示的區(qū)域暫稱之為視圖區(qū)域吧

審查元素,大致的效果如圖:

賊長(zhǎng)的這部分是所有的數(shù)據(jù)的盒子所占的大小,但是每次只控制小部分?jǐn)?shù)據(jù)在上面的盒子進(jìn)行顯示

虛擬列表的實(shí)現(xiàn)

怎么實(shí)現(xiàn)上面的效果?這里用到了固定定位和絕對(duì)定位

<script lang='ts' setup>
  type Item = {
    id: number
    name: string
  }
  const allListData = ref<Item[]>([])	// 存放十萬條數(shù)據(jù)
  const itemHeight = ref(40) // 每一條(項(xiàng))的高度
  const count = ref(10) // 一屏展示幾條數(shù)據(jù)
  const startIndex = ref(0) // 開始位置的索引
  const endIndex = ref(10) // 結(jié)束位置的索引
  const topVal = ref(0) // 父元素滾動(dòng)位置

  // 計(jì)算展示的列表
  const showListData = computed(() => allListData.value.slice(startIndex.value, endIndex.value))

  // 模擬十萬條數(shù)據(jù)
  const getData = async () => {
    for (let i = 0; i < 10000; i++) {
      allListData.value.push({ name: `第${i}條數(shù)據(jù)`, id: i })
    }
  }

  // 初始化加載
  onMounted(() => {
    getData()
  })

  // 虛擬列表視口區(qū)域的組件實(shí)例
  const viewport = ref<HTMLDivElement>()

    const handleScroll = () => {
      console.log('滾動(dòng)了')
      // 非空判斷
      if (!viewport.value) return
      // 獲取滾動(dòng)距離(這里通過組件實(shí)例獲取的,當(dāng)然也可以通過在該事件的事件參數(shù)中拿到)
      const scrollTop = viewport.value.scrollTop
      // 計(jì)算起始下標(biāo)和結(jié)束下標(biāo),用于 computed 計(jì)算
      startIndex.value = Math.floor(scrollTop / itemHeight.value)
      endIndex.value = startIndex.value + count.value
      // 動(dòng)態(tài)更改定位的 top 值,動(dòng)態(tài)展示相應(yīng)內(nèi)容
      topVal.value = viewport.value.scrollTop
    }
</script>

<template>
  <!-- 虛擬列表容器 -->
  <div
    class="viewport"
    ref="viewport"
    :style="{ height: 10條數(shù)據(jù)撐開的高度 }"
    >
    <!-- 占位元素,高度為所有的數(shù)據(jù)的總高度 -->
    <div
      class="placeholder"
      :style="{ height:itemHeight * count + 'px' }"
      ></div>
    <!-- 視圖區(qū),展示10條數(shù)據(jù),注意其定位的top值是變化的 -->
    <div class="list" :style="{ top: topVal + 'px' }">
      <!-- 每一條(項(xiàng))數(shù)據(jù) -->
      <div
        v-for="item in showListData"
        :key="item.id"
        class="item"
        :style="{ height: itemHeight + 'px' }"
        >
        {{ item.name }}
      </div>
    </div>
  </div>
</template>

  <style scoped lang="scss">
  .viewport {
  box-sizing: border-box;
  width: 240px;
  border: solid 1px #000000;
  // 開啟滾動(dòng)條
  overflow-y: auto;
  // 開啟相對(duì)定位
  position: relative;
  .list {
  width: 100%;
  height: auto;
  // 搭配使用絕對(duì)定位
  position: absolute;
  top: 0;
  left: 0;
  .item {
  box-sizing: border-box;
  width: 100%;
  height: 40px;
  line-height: 40px;
  text-align: center;
  // 隔行變色
  &:nth-child(even) {
  background: skyblue;
  }
  &:nth-child(odd) {
  background: #fff;
  }
  }
  }
  }
</style>

一開始視圖區(qū)域的top值為0,剛好在最頂端,監(jiān)聽滾動(dòng)事件,當(dāng)滾動(dòng)時(shí)實(shí)時(shí)改變top值以及該區(qū)域內(nèi)渲染的數(shù)據(jù),從而實(shí)現(xiàn)了虛擬列表

視圖區(qū)域的top值為什么要?jiǎng)討B(tài)監(jiān)聽?試想一下,現(xiàn)在所有數(shù)據(jù)的總高度為1000px,視圖區(qū)域?yàn)?00px,當(dāng)用戶滾動(dòng)到500px時(shí),如果視圖區(qū)域的top值不動(dòng)態(tài)綁定,那么視圖區(qū)域還停留在top=0(也就是最頂端處),那肯定就看不到最新的視圖了

到此這篇關(guān)于詳解Vue如何手寫一個(gè)虛擬列表的文章就介紹到這了,更多相關(guān)Vue虛擬列表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解vuex commit保存數(shù)據(jù)技巧

    詳解vuex commit保存數(shù)據(jù)技巧

    這篇文章主要介紹了詳解vuex commit保存數(shù)據(jù)技巧,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • elementUI表格多選框this.$refs.xxx.toggleRowSelection無效問題

    elementUI表格多選框this.$refs.xxx.toggleRowSelection無效問題

    這篇文章主要介紹了elementUI表格多選框this.$refs.xxx.toggleRowSelection無效問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Vue v-text指令簡(jiǎn)單使用方法示例

    Vue v-text指令簡(jiǎn)單使用方法示例

    這篇文章主要介紹了Vue v-text指令簡(jiǎn)單使用方法,結(jié)合實(shí)例形式分析了v-text指令文本輸出顯示簡(jiǎn)單操作技巧,需要的朋友可以參考下
    2019-09-09
  • Vue中 v-if/v-show/插值表達(dá)式導(dǎo)致閃現(xiàn)的原因及解決辦法

    Vue中 v-if/v-show/插值表達(dá)式導(dǎo)致閃現(xiàn)的原因及解決辦法

    在開發(fā)過程中經(jīng)常會(huì)發(fā)現(xiàn)當(dāng)頁面明明不應(yīng)該出現(xiàn)的元素或內(nèi)容會(huì)閃現(xiàn)一下然后消失,這篇文章給大家分享Vue中 v-if/v-show/插值表達(dá)式導(dǎo)致閃現(xiàn)的原因及解決辦法,一起看看吧
    2018-10-10
  • vue的狀態(tài)管理模式vuex

    vue的狀態(tài)管理模式vuex

    本篇文章主要介紹了深入理解vue的狀態(tài)管理模式vuex,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • vue+koa2實(shí)現(xiàn)session、token登陸狀態(tài)驗(yàn)證的示例

    vue+koa2實(shí)現(xiàn)session、token登陸狀態(tài)驗(yàn)證的示例

    這篇文章主要介紹了vue+koa2實(shí)現(xiàn)session、token登陸狀態(tài)驗(yàn)證的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 基于vue實(shí)現(xiàn)多引擎搜索及關(guān)鍵字提示

    基于vue實(shí)現(xiàn)多引擎搜索及關(guān)鍵字提示

    這篇文章主要為大家詳細(xì)介紹了基于vue實(shí)現(xiàn)多引擎搜索及關(guān)鍵字提示的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • vue實(shí)現(xiàn)購(gòu)物車結(jié)算功能

    vue實(shí)現(xiàn)購(gòu)物車結(jié)算功能

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)購(gòu)物車結(jié)算功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • 前端框架之封裝Vue第三方組件三個(gè)技巧

    前端框架之封裝Vue第三方組件三個(gè)技巧

    這篇文章主要為大家介紹了前端框架封裝Vue第三方組件的三個(gè)技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • vue中@keyup.enter失效問題及解決

    vue中@keyup.enter失效問題及解決

    這篇文章主要介紹了vue中@keyup.enter失效問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10

最新評(píng)論