靜態長列表優化
阿新 • • 發佈:2020-12-13
之前在商品模組的時候遇到一個這樣的問題多個規格組合在一起的時候 規格列表就會很長並且每一個規格都會有不同的價格跟會員價圖片等等資訊,所以會造成每一條商品資料會十分的臃腫再加上多條的話,對於商品規格資料的增刪改查操作的時候頁面會卡頓白屏操作甚至會載入不出來等情況
針對這一反饋我們的長列表優化就來了
思路
外層div 設定一個可以滾動的固定高度的盒子,
內層一個盒子通過計算所有條數的高度和 用來設定高度讓外層盒子可以滾動 可以通過絕對定位來設定 (作用:讓內部滾動起來,計算整體高度)
內層另外一個盒子用來顯示內容
對外層盒子繫結滾動事件得到滾動出去得高度 通過計算得到需要設定得資料 再設定內容的偏移量 跟滾動條高度持平 如此就達到了優化的目的了
css
<style> .list-view { height: 400px; overflow: auto; position: relative; border: 1px solid #aaa; } .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; /* transform: translateY(100px) !important;*/ /* background: red; */ } .list-view-item { padding: 5px; color: red; line-height: 30px; box-sizing: border-box; background: #666; margin: 10px 0; } </style>
html
<template> <div class="list-view" @scroll="handleScroll"> <div class="list-view-phantom" :style="{ height: contentHeight }" ></div> <div ref="content" class="list-view-content"> <div class="list-view-item" :style="{ height: itemHeight + 'px' }" v-for="(item, index) in list" :key="index" > <!-- {{ item }} --> <input type="text" v-model="item.value" /> </div> </div> </div> </template>
js
<script> export default { name: "ListView", props: { itemHeight: { type: Number, default: 30 } }, computed: { contentHeight() { return this.list.length * this.itemHeight + "px"; } }, mounted() { this.updateVisibleData(); }, created() { for (var i = 0; i < 1000; i++) { this.list.push({ value: i }); } }, data() { return { visibleData: [], //可視區域顯示的資料 list: [] // 總資料 }; }, methods: {//this.$refs.content.style.webkitTransform=`translateY(${start* this.itemHeight}px)`;
//更新資料 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.list.slice(start, end); // 擷取的資料
this.$refs.content.style.top = `${start * this.itemHeight}px`; // 內容展示區域跟滾動條位置平齊 這 }, // 繫結的滾動事件 handleScroll() { const scrollTop = this.$el.scrollTop; this.updateVisibleData(scrollTop); } } }; </script>