欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue中虛擬列表的原理與實現詳解

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

前言

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

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

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

什么是虛擬列表

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

虛擬列表的原理是什么

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

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

首先實現一個可以滑動的列表

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

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

<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>

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

實現虛擬列表

列表高度為300,列表項高度為50,那么我們只需要展示6條數據就可以了,因為有可能上拉數據,那么有可能展示第7條數據,所以我們要展示7條數據,但是首次加載我們只用展示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ū)域的列表,那么如何顯示滾動條呢

這個問題就是一個關鍵,需要我們設置一個虛擬的列表,定義好高度

<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>

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

現在我們的效果是這樣的,下拉的時候,列表內容都上移了

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

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

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

onScroll的實現包括以下幾個內容

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

所以我們的onScroll方法的實現是

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

此時我們的虛擬列表就實現了

完整代碼如下:

<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);
      // 列表結束索引
      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)化長列表或大數據集的用戶界面的技術,但它們有一些區(qū)別。

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

參考

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

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

相關文章

  • @click.native和@click的區(qū)別及說明

    @click.native和@click的區(qū)別及說明

    這篇文章主要介紹了@click.native和@click的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • vue幾個常用跨域處理方式介紹

    vue幾個常用跨域處理方式介紹

    本篇文章給大家詳細介紹了vue跨域處理問題的方式以及相關知識點介紹,對此有興趣的朋友學習下。
    2018-02-02
  • vue3+Element Plus實現自定義穿梭框的詳細代碼

    vue3+Element Plus實現自定義穿梭框的詳細代碼

    找到一個好用的vue樹形穿梭框組件都很難,又不想僅僅因為一個穿梭框在element-ui之外其他重量級插件,本文給大家分享vue3+Element Plus實現自定義穿梭框的示例代碼,感興趣的朋友一起看看吧
    2024-01-01
  • 詳解vue中computed 和 watch的異同

    詳解vue中computed 和 watch的異同

    本篇文章主要介紹了vue中computed 和 watch的異同,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • Vue中ElementUI結合transform使用時彈框定位不準確問題解析

    Vue中ElementUI結合transform使用時彈框定位不準確問題解析

    在近期開發(fā)中,需要將1920*1080放到更大像素大屏上演示,所以需要使用到transform來對頁面進行縮放,但是此時發(fā)現彈框定位出錯問題,無法準備定位到實際位置,本文給大家分享Vue中ElementUI結合transform使用時彈框定位不準確解決方法,感興趣的朋友一起看看吧
    2024-01-01
  • vue中el表單的簡單查詢方法

    vue中el表單的簡單查詢方法

    本文主要介紹了vue中el表單的簡單查詢方法,主要包括表單頁面根據groupid 、type 、errortype進行數據過濾,感興趣的可以了解一下
    2023-10-10
  • 詳解Vue調用手機相機和相冊以及上傳

    詳解Vue調用手機相機和相冊以及上傳

    這篇文章主要介紹了Vue調用手機相機及上傳,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • element-ui?tree?異步樹實現勾選自動展開、指定展開、指定勾選功能

    element-ui?tree?異步樹實現勾選自動展開、指定展開、指定勾選功能

    這篇文章主要介紹了element-ui?tree?異步樹實現勾選自動展開、指定展開、指定勾選,項目中用到了vue的element-ui框架,用到了el-tree組件,由于數據量很大,使用了數據懶加載模式,即異步樹,需要的朋友可以參考下
    2022-08-08
  • VUE?v-for中的:key詳解

    VUE?v-for中的:key詳解

    這篇文章主要為大家介紹了v-for中的:key,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • vue如何在多個不同服務器下訪問不同地址

    vue如何在多個不同服務器下訪問不同地址

    這篇文章主要介紹了vue如何在多個不同服務器下訪問不同地址,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評論