如果后端一次返回数据量较大,而且要用列表的形式展现给用户,如果我们不做处理的话,在浏览器中渲染大量 dom节点,是极其耗费时间的
< template>
< div class = " list_view" @scroll = " handleScroll" >
< div class = " scroll_area" :style = " { height: scrollAreaHeight }" > </ div>
< div ref = " content" class = " list_view_content" >
< div
class = " list_view_item"
:style = " { height: itemHeight + ' px' }"
v-for = " (item,index) in showList"
:key = " index"
>
< div class = " box_itme" >
< div class = " itme_img" > {{ item.img }}</ div>
< div class = " itme_name" > {{ item.name }}</ div>
</ div>
</ div>
</ div>
</ div>
</ template>
< script>
export default {
name : 'ListView' ,
props : {
list : {
type : Array,
default : ( ) => [ ]
} ,
itemHeight : {
type : Number,
default : 30
}
} ,
data ( ) {
return {
showNum : 20 ,
start : 0 ,
end : 20 ,
} ;
} ,
computed : {
scrollAreaHeight ( ) {
return this . list. length * this . itemHeight + 'px' ;
} ,
showList ( ) {
return this . list. slice ( this . start, this . end) ;
}
} ,
mounted ( ) {
this . computescrollArea ( ) ;
window. addEventListener ( 'resize' , ( ) => {
this . $nextTick ( ( ) => {
this . handleScroll ( )
} )
} )
} ,
methods : {
computescrollArea ( scrollTop ) {
scrollTop = scrollTop || 0 ;
this . showNum = Math. ceil ( this . $el. clientHeight / this . itemHeight) ;
this . start = Math. floor ( scrollTop / this . itemHeight) ;
this . end = this . start + this . showNum;
this . $refs. content. style. webkitTransform = ` translate3d(0, ${ this . start * this . itemHeight} px, 0) ` ;
} ,
handleScroll ( ) {
const scrollTop = this . $el. scrollTop;
this . computescrollArea ( scrollTop) ;
}
}
}
</ script>
< style>
.list_view {
width : 500px;
margin : 0 auto;
height : calc ( 100vh - 100px) ;
overflow : auto;
position : relative;
border : 1px solid #aaa;
}
.scroll_area {
position : absolute;
left : 0;
top : 0;
right : 0;
z-index : -1;
}
.list_view_content {
scroll-behavior : smooth;
left : 0;
right : 0;
top : 0;
position : absolute;
}
.list_view_item {
padding : 5px;
color : #666;
height : 50px;
box-sizing : border-box;
margin-bottom : 10px;
}
.box_itme {
width : 100%;
height : 100%;
display : flex;
align-items : center;
}
.box_itme >div {
height : 100%;
display : flex;
align-items : center;
justify-content : center;
}
.itme_img {
background-color : #eee;
flex : 0.3;
}
.itme_name {
background-color : #f8f8f8;
flex : 0.7;
}
</ style>
使用
< template>
< div id = " home" >
< xn2 :list = " list" :itemHeight = " 100" > </ xn2>
</ div>
</ template>
< script>
import xn2 from "../components/xn2.vue" ;
export default {
components : {
xn2
} ,
data ( ) {
return {
list : [ ] ,
} ;
} ,
created ( ) {
for ( let index = 0 ; index < 100000 ; index++ ) {
this . list. push ( {
id : index,
name : '第' + index + '个' ,
img : 'url' + index,
} )
}
} ,
} ;
</ script>