最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue中虛擬列表的原理與實現(xiàn)詳解

 更新時間:2023年05月23日 11:37:35   作者:為了摸魚而戰(zhàn)  
虛擬列表是一種技術(shù),它只渲染用戶當前可見的列表項,而不是渲染整個列表,這篇文章主要來和大家聊聊虛擬列表的原理與實現(xiàn),希望對大家有所幫助

前言

最近在工作中遇到了一個列表的需求,因為做的是C端,所以對性能體驗要求很高,主要有下面幾點要求,也可以說是痛點

  • 就算加載上千條數(shù)據(jù),也能夠立即加載,而不會卡頓,等待時間不能太長
  • 加載好以后用戶能立馬進行交互,而不是要等待,體驗必須絲滑

仔細想想, 加載上千條數(shù)據(jù),加載時間肯定會相對長一些,而又要求立即加載,這不是一個矛盾的需求么,所以如果使用常規(guī)的操作,肯定難以解決這個痛點,所以必須引出我們今天的主角才能解決今天的問題

什么是虛擬列表

虛擬列表是一種技術(shù),它只渲染用戶當前可見的列表項,而不是渲染整個列表。

虛擬列表的原理是什么

只渲染可視區(qū)域內(nèi)的列表項,而不是渲染整個列表

當用戶滾動容器時,虛擬列表會根據(jù)滾動位置和可視區(qū)域的大小計算出當前應該顯示的列表項。

首先實現(xiàn)一個可以滑動的列表

因為我們主要講的是虛擬列表,為了不增加大家負擔,那么列表容器的高度,列表項的高度,我們都設(shè)置為已知的,而實際使用的時候,可以根據(jù)場景,動態(tài)獲取

代碼很簡單,然后我們一次性渲染10萬條數(shù)據(jù)數(shù)據(jù)

<template>
  <div class="about">
    <div class="scrollView">
      <div class="list">
        <div class="item" v-for="item in list" :key="item">
          {{ item }}
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      list: [],
    };
  },
  mounted() {
    const total = 100000;
    const list = [];
    for (let i = 0; i < total; i++) {
      list.push(i);
    }
    this.list = list;
  }
};
</script>
<style>
.scrollView {
  width: 200px;
  height: 300px;
  background-color: red;
  overflow-y: scroll;
  position: relative;
}
.item {
  height: 50px;
}
</style>

測試結(jié)果非??植?,因為數(shù)據(jù)量龐大,發(fā)現(xiàn)才開始的時候一直卡著不動,有1s多的時間是什么也看不到的,這無疑是致命的

實現(xiàn)虛擬列表

列表高度為300,列表項高度為50,那么我們只需要展示6條數(shù)據(jù)就可以了,因為有可能上拉數(shù)據(jù),那么有可能展示第7條數(shù)據(jù),所以我們要展示7條數(shù)據(jù),但是首次加載我們只用展示6條

所以此時我們改一下mounted生命周期

  mounted() {
    const total = 100000;
    const list = [];
    for (let i = 0; i < total; i++) {
      list.push(i);
    }
    this.data = list;
    this.list = list.slice(0, 6);
  },

問題一:我們只展示可視區(qū)域的列表,那么如何顯示滾動條呢

這個問題就是一個關(guān)鍵,需要我們設(shè)置一個虛擬的列表,定義好高度

<template>
  <div class="about">
    <div class="scrollView" @scroll="onScroll" ref="list">
      <!-- 虛擬列表 -->
      <div class="virtualScroller" :style="{ height: listHeight + 'px' }"></div> 
      <div class="list">
        <div class="item" v-for="item in list" :key="item">
          {{ item }}
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      list: [],
      listHeight: 0,
      itemSize: 50,
      containerHeight: 300,
      visibleCount: 6,
      data: [],
      startOffset: 0,
    };
  },
  mounted() {
    ....
    this.listHeight = list.length * this.itemSize;
    .....
  }
};
</script>
<style>
.list {
  position: absolute;
  top: 0;
  left: 0;
}
</style>

問題二:下拉列表以后,如何讓列表內(nèi)容顯示到可視區(qū)域內(nèi)

現(xiàn)在我們的效果是這樣的,下拉的時候,列表內(nèi)容都上移了

所以我們要讓列表內(nèi)容在滾動的時候,移動到可視區(qū)域內(nèi)

我們監(jiān)聽scrollView的 scroll事件

<div class="scrollView" @scroll="onScroll" ref="list">

onScroll的實現(xiàn)包括以下幾個內(nèi)容

  • 滾動距離:scrollTop
  • 列表開始索引:startIndex
  • 列表結(jié)束索引:endIndex
  • 列表移動距離:startOffset: 這個是重點
this.startOffset = scrollTop - (scrollTop % this.itemSize);

所以我們的onScroll方法的實現(xiàn)是

onScroll() {
       //當前滾動位置
      let scrollTop = this.$refs.list.scrollTop;
      // 列表開始索引
      let startIndex = Math.floor(scrollTop / this.itemSize);
      // 列表結(jié)束索引
      let endIndex = Math.ceil((scrollTop + this.containerHeight) / this.itemSize);
      this.list = this.data.slice(startIndex, endIndex);
      // 列表移動距離
      this.startOffset = scrollTop - (scrollTop % this.itemSize);
    }

此時我們的虛擬列表就實現(xiàn)了

完整代碼如下:

<template>
  <div class="about">
    <div class="scrollView" @scroll="onScroll" ref="list">
      <!-- 虛擬列表 -->
      <div class="virtualScroller" :style="{ height: listHeight + 'px' }"></div>
      <div class="list" :style="{ transform: `translateY(${this.startOffset}px)` }">
        <div class="item" v-for="item in list" :key="item">
          {{ item }}
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      list: [],
      listHeight: 0,
      itemSize: 50,
      containerHeight: 300,
      visibleCount: 6,
      data: [],
      startOffset: 0,
    };
  },
  mounted() {
    const total = 100000;
    const list = [];
    for (let i = 0; i < total; i++) {
      list.push(i);
    }
    this.listHeight = list.length * this.itemSize;
    this.data = list;
    this.list = list.slice(0, 6);
  },
  methods: {
    onScroll() {
        //當前滾動位置
      let scrollTop = this.$refs.list.scrollTop;
      // 列表開始索引
      let startIndex = Math.floor(scrollTop / this.itemSize);
      // 列表結(jié)束索引
      let endIndex = Math.ceil((scrollTop + this.containerHeight) / this.itemSize);
      this.list = this.data.slice(startIndex, endIndex);
      // 列表移動距離
      this.startOffset = scrollTop - (scrollTop % this.itemSize);
    }
  }
};
</script>
<style>
.scrollView {
  width: 200px;
  height: 300px;
  background-color: red;
  overflow-y: scroll;
  position: relative;
}
.item {
  height: 50px;
}
.list {
  position: absolute;
  top: 0;
  left: 0;
}
</style>

那么虛擬列表和下拉加載更多有什么區(qū)別呢

虛擬列表(Virtual List)和下拉加載更多(Infinite Scroll)都是用于優(yōu)化長列表或大數(shù)據(jù)集的用戶界面的技術(shù),但它們有一些區(qū)別。

虛擬列表通過動態(tài)渲染當前可見的列表項來提高性能和內(nèi)存利用率,而下拉加載更多是在用戶滾動到列表底部時自動加載更多數(shù)據(jù)。兩者都是為了優(yōu)化大數(shù)據(jù)集或長列表的用戶界面,提供更好的性能和用戶體驗。具體選擇哪種技術(shù)取決于具體的需求和場景。

參考

「前端進階」高性能渲染十萬條數(shù)據(jù)(虛擬列表)

到此這篇關(guān)于Vue中虛擬列表的原理與實現(xiàn)詳解的文章就介紹到這了,更多相關(guān)Vue虛擬列表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • nuxt踩坑之Vuex狀態(tài)樹的模塊方式使用詳解

    nuxt踩坑之Vuex狀態(tài)樹的模塊方式使用詳解

    這篇文章主要介紹了nuxt踩坑之Vuex狀態(tài)樹的模塊方式使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • Vue頁面首次載入優(yōu)化的全過程

    Vue頁面首次載入優(yōu)化的全過程

    凡是做SPA的項目,特別是移動端的SAP項目,首屏加載速度必定是一個繞不過去的話題,下面這篇文章主要給大家介紹了關(guān)于Vue頁面首次載入優(yōu)化的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • vue實現(xiàn)列表無縫滾動效果

    vue實現(xiàn)列表無縫滾動效果

    這篇文章主要為大家詳細介紹了vue實現(xiàn)列表無縫滾動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Vue3?UI組件庫Element?Plus實例詳解

    Vue3?UI組件庫Element?Plus實例詳解

    這篇文章主要介紹了ElementPlus框架中的一些常用組件,通過示例代碼展示了這些組件的具體使用方法,本文結(jié)合示例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2026-05-05
  • VueX學習之modules和namespacedVueX詳細教程

    VueX學習之modules和namespacedVueX詳細教程

    這篇文章主要為大家介紹了VueX學習之modules和namespacedVueX詳細教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • vue3使用vue-router及路由權(quán)限攔截方式

    vue3使用vue-router及路由權(quán)限攔截方式

    這篇文章主要介紹了vue3使用vue-router及路由權(quán)限攔截方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue項目中掃碼支付的實現(xiàn)示例(附demo)

    vue項目中掃碼支付的實現(xiàn)示例(附demo)

    本文主要介紹了vue項目中掃碼支付的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 教你使用vue3寫Json-Preview的示例代碼

    教你使用vue3寫Json-Preview的示例代碼

    這篇文章主要介紹了用vue3寫了一個Json-Preview的相關(guān)知識,引入后直接<json-preview?v-model="jsonData"></json-preview>就可以使用了,本文通過示例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • element ui表格實現(xiàn)下拉篩選功能

    element ui表格實現(xiàn)下拉篩選功能

    這篇文章主要為大家詳細介紹了element ui表格實現(xiàn)下拉篩選功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • vue中elementUI里面一些插件的使用

    vue中elementUI里面一些插件的使用

    Element UI是一套基于Vue的桌面端組件庫,封裝好了很多常用的UI組件,下面這篇文章主要給大家介紹了關(guān)于vue中elementUI里面一些插件的使用方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06

最新評論

焦作市| 洛宁县| 兖州市| 醴陵市| 洛隆县| 夏邑县| 措勤县| 牡丹江市| 昌图县| 汶上县| 八宿县| 武川县| 获嘉县| 鄄城县| 红河县| 洛川县| 东明县| 济宁市| 南靖县| 科尔| 虞城县| 丰城市| 南丰县| 崇仁县| 政和县| 晋中市| 天津市| 华池县| 台北县| 怀柔区| 剑川县| 定西市| 高碑店市| 莆田市| 漳浦县| 洮南市| 湟源县| 鲁甸县| 石楼县| 鄂温| 松溪县|