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

基于Vue3實(shí)現(xiàn)列表虛擬滾動效果

 更新時間:2022年04月15日 10:11:35   作者:yellowhomecar  
這篇文章主要為大家介紹了如何利用Vue3實(shí)現(xiàn)列表虛擬滾動效果,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定價值,需要的可以參考一下

前言

近期在做一個網(wǎng)頁播放器項(xiàng)目中,用到很多需要展示歌單的列表

一個歌單動輒千百首歌曲,頁面中的元素太多導(dǎo)致熱重載的時候 chrome 直接崩了 ??

于是無限滾動列表提上日程

寫的有點(diǎn)亂,也是第一次用 typescript 寫項(xiàng)目,先記錄一下

完成效果

思路和需要解決的問題

與懶加載不同,虛擬滾動需要一次性獲取所有數(shù)據(jù),但是只顯示屏幕可見范圍內(nèi)的數(shù)據(jù)

要做到這些我需要知道:

  • 一行的高度
  • 屏幕范圍內(nèi)能顯示的行數(shù)
  • 列表在頁面中距離網(wǎng)頁頂部的位置
  • 滾動條高度

假設(shè)滿屏能容納 10 條數(shù)據(jù),需要加載的數(shù)據(jù)是一個數(shù)組listData,只需要裁剪數(shù)據(jù)范圍listData.slice(0, 10)

隨著滾動條向下,將滾動條高度/一行的高度可以計(jì)算出當(dāng)前行數(shù)

而要模擬滾動條高度就要在頁面掛載時就手動設(shè)置頁面的高度一行高度*listData.length

最后也是最關(guān)鍵的是保持列表一直保持在當(dāng)前位置上,手動設(shè)置列表容器padding-top等于當(dāng)前滾動條高度

有一個仍未解決的問題,就是每次來回滾動歌曲封面都要重新請求 ??

vue3+setup 寫的組件

<script lang="ts" setup>
import { ref, computed, nextTick, reactive, watchEffect, onUnmounted } from 'vue'

const props = defineProps<{
  listData: Array<any>
}>()

// 列表HTMLElementDom
const ulRef = ref<any>(null)

// 屏幕高度
const screenH = document.documentElement.clientHeight

const data = reactive<any>({
  // 列表第一項(xiàng)的高度(起始高度)
  initH: 0,

  // 一行的高度
  unitH: 0,

  // 屏幕范圍內(nèi)能顯示個數(shù)
  displayCount: 1,

  // 列表起始值
  startIdx: 0
})

const listData = computed(() => {
  let endIdx = data.startIdx + data.displayCount
  if (endIdx >= props.listData.length) endIdx = props.listData.length

  return props.listData.slice(data.startIdx, endIdx).map((v, k) => {
    v.idx = data.startIdx + k + 1
    return v
  })
})

function scrollHandler() {
  // 當(dāng)前滾動高度
  const curScrollTop = document.documentElement.scrollTop
  if (curScrollTop > data.initH) {
    const addCount = Math.floor((curScrollTop - data.initH) / data.unitH)
    ulRef.value.style.setProperty('padding-top', `${addCount * data.unitH}px`)
    data.startIdx = addCount
  } else {
    ulRef.value.style.setProperty('padding-top', '0px')
    data.startIdx = 0
  }
}

watchEffect(() => {
  if (props.listData.length > 0) {
    nextTick(() => {
      // 列表距離頂部距離
      data.initH = ulRef.value.getBoundingClientRect().top + document.documentElement.scrollTop
      // 計(jì)算每行高度
      data.unitH = ulRef.value.children[0].offsetHeight
      // 計(jì)算屏幕內(nèi)能顯示的行數(shù)
      data.displayCount = Math.ceil(screenH / data.unitH)
      // 設(shè)置列表總高度 = 一行高度 * 行數(shù)
      const listH = data.unitH * props.listData.length
      ulRef.value.style.setProperty('height', `${listH}px`)

      window.removeEventListener('scroll', scrollHandler)
      window.addEventListener('scroll', scrollHandler)
    })
  }
})

onUnmounted(() => {
  window.removeEventListener('scroll', scrollHandler)
})
</script>

<template>
  <ul ref="ulRef">
    <li v-for="(listItem, listIndex) in listData" :key="`list-${listIndex}`" :data-idx="listItem.idx">
      <slot :listItem="listItem"></slot>
    </li>
  </ul>
</template>

使用組件

<script lang="ts" setup>
import InfiniteList from './InfiniteList.vue'

const songs = [] // 列表數(shù)據(jù)
</script>

<template>
  <infinite-list :listData="songs">
    <template #default="{ listItem }">
      <div>{{ listItem.title }}</div>
      <!-- ... -->
    </template>
  </infinite-list>
</template>

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

相關(guān)文章

  • 使用Element+vue實(shí)現(xiàn)開始與結(jié)束時間限制

    使用Element+vue實(shí)現(xiàn)開始與結(jié)束時間限制

    這篇文章主要為大家詳細(xì)介紹了使用Element+vue實(shí)現(xiàn)開始與結(jié)束時間限制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 解決vue props傳Array/Object類型值,子組件報(bào)錯的情況

    解決vue props傳Array/Object類型值,子組件報(bào)錯的情況

    這篇文章主要介紹了解決vue props傳Array/Object類型值,子組件報(bào)錯的情況,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • vue 實(shí)現(xiàn)微信浮標(biāo)效果

    vue 實(shí)現(xiàn)微信浮標(biāo)效果

    微信的浮窗,大伙應(yīng)該都用過,當(dāng)我們正在閱讀一篇公眾號文章時,突然需要處理微信消息,點(diǎn)擊浮窗,在微信上會有個浮標(biāo),點(diǎn)擊浮標(biāo)可以再次回到文章。今天小編抽空給大家介紹vue 實(shí)現(xiàn)微信浮標(biāo)效果,感興趣的朋友一起看看吧
    2019-09-09
  • Vue js with語句原理及用法解析

    Vue js with語句原理及用法解析

    這篇文章主要介紹了Vue js with語句原理及用法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • vue-cli3在main.js中console.log()會報(bào)錯的解決

    vue-cli3在main.js中console.log()會報(bào)錯的解決

    這篇文章主要介紹了vue-cli3在main.js中console.log()會報(bào)錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue.js通過自定義指令實(shí)現(xiàn)數(shù)據(jù)拉取更新的實(shí)現(xiàn)方法

    vue.js通過自定義指令實(shí)現(xiàn)數(shù)據(jù)拉取更新的實(shí)現(xiàn)方法

    數(shù)據(jù)拉取更新這個功能相信大家基本都見過,但是如果要做起來卻不止如何做起,所以這篇文章給大家分享了vue.js通過自定義指令實(shí)現(xiàn)的方法,閱讀本文需要對vue有一定理解,有需要的朋友們下面來一起看看吧。
    2016-10-10
  • 通過vue-cli3構(gòu)建一個SSR應(yīng)用程序的方法

    通過vue-cli3構(gòu)建一個SSR應(yīng)用程序的方法

    這篇文章主要介紹了通過vue-cli3構(gòu)建一個SSR應(yīng)用程序,以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
    2018-09-09
  • 阿望教你用vue寫掃雷小游戲

    阿望教你用vue寫掃雷小游戲

    這篇文章主要介紹了阿望教你用vue寫掃雷小游戲,本文通過實(shí)例代碼效果圖展示的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • Vue渲染流程步驟詳解

    Vue渲染流程步驟詳解

    在Vue里渲染一塊內(nèi)容,會有四個流程步驟,那么該怎么理解這個流程呢,所以本文就給大家詳細(xì)講解一下Vue 渲染流程,文中有纖細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2023-07-07
  • vue通過v-show實(shí)現(xiàn)回到頂部top效果

    vue通過v-show實(shí)現(xiàn)回到頂部top效果

    這篇文章主要介紹了vue通過v-show實(shí)現(xiàn)回到頂部top效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12

最新評論

鄂尔多斯市| 石家庄市| 石阡县| 定襄县| 巨鹿县| 离岛区| 天峻县| 泸定县| 阿坝| 同德县| 德阳市| 北京市| 登封市| 屯留县| 沂水县| 方山县| 全椒县| 上饶县| 长沙市| 房产| 南昌县| 米易县| 美姑县| 柏乡县| 浮山县| 高尔夫| 抚宁县| 吴忠市| 静宁县| 荔波县| 蓬溪县| 德格县| 汝城县| 台中市| 鄂托克旗| 获嘉县| 保山市| 越西县| 格尔木市| 昭苏县| 稻城县|