<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
vxe-table vxe-list vue 實現下拉框的虛擬列表
只渲染可視區的 dom 節點,其餘不可見的資料捲起來,只會渲染可視區域的 dom 節點,提高渲染效能及流暢性,優點是支援海量資料的渲染;當然也會有缺點:捲動效果相對略差(海量資料與捲動效果的取捨問題就看自己的需求嘍);
<div class="my-select"> <input type="text" class="my-select-input" readonly> <vxe-list class="my-select-wrapper" :loading="loading" :data="list"> <template v-slot="{ items }"> <div class="my-select-option" v-for="item in items" :key="item.value">{{ item.label }}</div> </template> </vxe-list> </div>
export default { data () { return { loading: false, list: [] } }, created () { this.loading = true setTimeout(() => { const startTime = Date.now() var list = [] for(var i=0;i<100000;i++){ list.push({ label: '選項'+i, value: i }) } this.list = list this.loading = false this.$nextTick(() => { this.$XModal.message({ message: `渲染 ${list.length} 行,用時 ${Date.now() - startTime}毫秒`, status: 'info' }) }) }, 200) } }
.my-select { width: 200px; position: relative; background-color: #fff; } .my-select-input { width: 100%; height: 24px; border: 1px solid #dcdfe6; } .my-select-wrapper { position: absolute; left: 0; top: 26px; width: 100%; height: 200px; background-color: #fff; border: 1px solid #dcdfe6; } .my-select-option:hover { background-color: #f5f7fa; cursor: pointer; }
渲染 1w 條只需要 150 毫秒左右
渲染 5w 條只需要 300 毫秒左右
渲染 10w 條只需要 500 毫秒左右
具體用法可以去看 官方檔案,線上執行 http://jsrun.net/CW2Kp/edit
前端的業務開發中會遇到不使用分頁方式來載入長列表的需求。如在資料長度大於 1000 條情況,DOM 元素的建立和渲染需要的時間成本很高,完整渲染列表所需要的時間不可接受,同時會存在捲動時卡頓問題;
解決該卡頓問題的重點在於如何降低長列表DOM渲染成本問題,文章將介紹通過虛擬列表渲染的方式解決該問題。
為什麼需要虛擬列表
虛擬列表是對長列表的一種優化方案。在前端開發中,會碰到一些不能使用分頁方式來載入列表資料的業務形態,我們稱這種列表叫做長列表。比如,手機端,淘寶商品展示,美團外賣等,資料量特別龐大,不適合分頁,以及懶載入,這時候我們可以採用虛擬列表,只展示可視區域資料。
虛擬列表的核心思想為可視區域渲染,在頁面捲動時對資料進行擷取、複用DOM進行展示的渲染方式。
實現虛擬列表就是處理卷軸捲動後的可見區域的變更,其中具體步驟如下:
1.計算當前可見區域起始資料的 startIndex
2.計算當前可見區域結束資料的 endIndex
3.計算當前可見區域的資料,並渲染到頁面中
4.計算 startIndex 對應的資料在整個列表中的偏移位置 startOffset,並設定到列表上
我們首先要考慮的是虛擬列表的 HTML、CSS 如何實現:
html:
<template> <div class="list-view" :style="{ height: `${height}px` }" @scroll="handleScroll"> <div class="list-view-phantom" :style="{ height: contentHeight }"> </div> <ul ref="content" class="list-view-content"> <li class="list-view-item" :style="{ height: itemHeight + 'px' }" v-for="(item, index) in visibleData" :key="index"> {{ item }} </li> </ul> </div> </template>
script:
<script> export default { name: 'ListView', props: { data: { type: Array, default: function() { const list = [] for (let i = 0; i < 1000000; i++) { list.push('列表' + i) } return list } }, height: { type: Number, default: 400 }, itemHeight: { type: Number, default: 30 }, }, computed: { contentHeight() { return this.data.length * this.itemHeight + 'px'; } }, mounted() { this.updateVisibleData(); }, data() { return { visibleData: [] }; }, methods: { updateVisibleData(scrollTop) { scrollTop = scrollTop || 0; const visibleCount = Math.ceil(this.$el.clientHeight / this.itemHeight); // 取得可見區域的可見列表項數量 const start = Math.floor(scrollTop / this.itemHeight); // 取得可見區域的起始資料索引 const end = start + visibleCount; // 取得可見區域的結束資料索引 this.visibleData = this.data.slice(start, end); // 計算出可見區域對應的資料,讓 Vue.js 更新 this.$refs.content.style.webkitTransform = `translate3d(0, ${ start * this.itemHeight }px, 0)`; // 把可見區域的 top 設定為起始元素在整個列表中的位置(使用 transform 是為了更好的效能) }, handleScroll() { const scrollTop = this.$el.scrollTop; this.updateVisibleData(scrollTop); } } } </script>
css:
<style lang="scss" scoped> .list-view { overflow: auto; position: relative; border: 1px solid #aaa; width: 200px; } .list-view-phantom { position: absolute; left: 0; top: 0; right: 0; z-index: -1; } .list-view-content { left: 0; right: 0; top: 0; position: absolute; } .list-view-item { padding: 5px; color: #666; line-height: 30px; box-sizing: border-box; } </style>
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45