vue虛擬化列表封裝的實現
vue虛擬化列表封裝
將下面代碼復制一份到自己的項目中
<template>
<div class="scrollParent" ref="scrollContent" @scroll="handleScroll">
<div :style="blankFillStyle">
<div v-for="item,index in showDataList" :key="index">
<slot :everyVirtual="item"></slot>
</div>
</div>
</div>
</template><script>
export default {
? ? props:["oneHeight","virtualList"],
? ? data () {
? ? ? ? return {
? ? ? ? ? ? contentSize:"", //可視區(qū)域可以展示多少條數據
? ? ? ? ? ? startIndex:0, //記錄當前滾動的第一個元素的索引
? ? ? ? ? ? currentScroll:0, ?//記錄當前滾動的距離
? ? ? ? }
? ? },
? ? methods:{
? ? ? ? // 獲取可視區(qū)域可以展示多少條
? ? ? ? getContentSize(){
? ? ? ? ? ? // 兩次取反可以獲取到整數部分
? ? ? ? ? ? this.contentSize = ~~(this.$refs.scrollContent.offsetHeight / this.oneHeight) + 2;
? ? ? ? },
? ? ? ? // 監(jiān)聽滾動條
? ? ? ? handleScroll(){
? ? ? ? ? ? // 持續(xù)滾動 ?減少變量重新賦值 ?優(yōu)化處理 只有在到下一個元素節(jié)點的時候才會重新給this.statrIndex賦值 ?避免和this.startIndex相關聯的數據再次計算
? ? ? ? ? ? this.currentScroll = this.$refs.scrollContent.scrollTop;
? ? ? ? ? ? let currentIndex = ~~(this.$refs.scrollContent.scrollTop/this.oneHeight);
? ? ? ? ? ? if(this.startIndex == currentIndex){
? ? ? ? ? ? ? ? return
? ? ? ? ? ? }
? ? ? ? ? ? this.startIndex = currentIndex;
? ? ? ? ? ? if((this.startIndex + this.contentSize - 1)>this.virtualList.length-1){ //說明到達底部了
? ? ? ? ? ? ? ? this.$emit("scrollEnd")
? ? ? ? ? ? }
? ? ? ? }
? ? },
? ? activated(){
? ? ? ? this.$nextTick(()=>{
? ? ? ? ? ? this.$refs.scrollContent.scrollTop = this.currentScroll;
? ? ? ? })
? ? },
? ? computed:{
? ? ? ? endIndex(){ //獲取最后一個元素的索引
? ? ? ? ? ? let endIndex = this.startIndex + this.contentSize*2;
? ? ? ? ? ? if(endIndex>this.virtualList.length-1){
? ? ? ? ? ? ? ? endIndex = this.virtualList.length-1
? ? ? ? ? ? }
? ? ? ? ? ? return endIndex;
? ? ? ? },
? ? ? ? showDataList(){
? ? ? ? ? ? let startIndex = 0;
? ? ? ? ? ? if(this.startIndex<=this.contentSize){
? ? ? ? ? ? ? ? startIndex = 0;
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? startIndex = this.startIndex - this.contentSize;
? ? ? ? ? ? }
? ? ? ? ? ? return this.virtualList.slice(startIndex,this.endIndex);
? ? ? ? },
? ? ? ? blankFillStyle(){
? ? ? ? ? ? let startIndex = 0;
? ? ? ? ? ? if(this.startIndex<=this.contentSize){
? ? ? ? ? ? ? ? startIndex = 0;
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? startIndex = this.startIndex - this.contentSize;
? ? ? ? ? ? }
? ? ? ? ? ? return{
? ? ? ? ? ? ? ? paddingTop:startIndex * this.oneHeight + "px",
? ? ? ? ? ? ? ? paddingBottom:(this.virtualList.length - this.endIndex) * this.oneHeight +"px"
? ? ? ? ? ? }
? ? ? ? }
? ? },
? ? mounted(){
? ? ? ? window.onresize = this.getContentSize();
? ? ? ? window.orientationchange = this.getContentSize();
? ? }
}
</script><style scoped>
? ? .scrollParent{
? ? ? ? height: 100%;
? ? ? ? width: 100%;
? ? ? ? overflow-y: auto;
? ? }
</style>vue虛擬列表-vue-virtual-scroll-list
使用場景
因為公司做了類似于百度網盤的競品,所以用戶如果上傳了很多的文件,就會造成頁面DOM元素的過多,然后因為需要操作DOM元素,所以頁面會變得很卡。所以用虛擬列表來解決。

安裝
安裝的話這個插件有2個版本的,一個是1版本,目前更新到2版本了,二版本功能更加的強大。這里使用了1版本,通俗易懂一點。
npm install --save vue-virtual-scroll-list@1.1.3
使用
在單頁面中導入
import VirtualList from "vue-virtual-scroll-list";
components: {
VirtualList,//注冊組件
}, <div class="content-timeview_box">
<!-- size代表行高 remain代表一次渲染的數量 -->
<!-- 出現的問題:1.在時間視圖時(文件夾視圖只有一個VirtualList不受影響) 一個日期代表一個VirtualList 怎么解決高度問題? -->
<!-- 如果統(tǒng)一高度?一個日期中的文件數量少于高度 就會出現VirtualList之間的空白問題 -->
<!-- 應該根據日期下的文件數量來動態(tài)的綁定每一個VirtualList的高度 -->
<VirtualList
:size="40"
:remain="17"
:wclass="vuesrollboxviewClass"
:tobottom="toBottom"
style="padding: 0 32px 0 32px"
:style="{height:itembig.items.length>6?scrollbarheight:'200px'}"
>toBottom的方法,這個地方就很坑,因為我只能在1.1.3版本中觸發(fā)這個方法,1版本的其他版本號我沒有觸發(fā)成功,應該還是高度的問題。toBottom:滾動到底部時觸發(fā),請求下一組數據
//滾到底部時觸發(fā)
//注:此方法在1.0高版本不兼容,只能在官方文檔1.1.3版本中使用
//@1.1.3
toBottom() {
this.infiniteHandler();
},:wclass=“vuesrollboxviewClass”
wclass是自定義的class,我這里的業(yè)務場景不是每行只有1個數據,從上而下排列下來,而是每行根據分辨率不同,展示5個或6個,所以得計算好一次渲染的個數,需要動態(tài)的綁定。


小結:還是需要更熟練的掌握原生JS,雖然有各種各樣的框架插件來解決問題,但是碰到業(yè)務場景更復雜的時候呢?所以還是要掌握原生JS,具備自己寫輪子的能力才行。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
vue的.vue文件是怎么run起來的(vue-loader)
通過vue-loader,解析.vue文件,在webpack解析,拆解vue組件 ,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友參考下2018-12-12
vscode中prettier和eslint換行縮進沖突的問題
這篇文章主要介紹了vscode中prettier和eslint換行縮進沖突的問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10

