当前位置:网站首页>Understand the principle behind the virtual list, and easily realize the virtual list
Understand the principle behind the virtual list, and easily realize the virtual list
2022-07-28 13:59:00 【Maic】
In the project , Big data rendering often encounters , such as
umy-ui(ux-table) Virtual list table Components ,vue-virtual-scrolleras well asreact-virtualizedThese excellent plug-ins quickly meet business needs .
In order to understand the principle and mechanism behind the plug-in , We implement a simple version of our virtual list , I hope it can bring some thinking and help in the actual business project .
Text begins ...
What is a virtual list
In big data rendering , Select a visual area to display the corresponding data .
Let's take a preliminary look at a picture
In this illustration , We can see that what we show is always Red dotted line Part of the show , Each element has a fixed height , By a Very high elements Wrapped in , also Outermost layer There is a fixed height container , And the settings can scroll .
Create a new one index.html The corresponding structure is as follows
...
<div class="vitual-list-wrap" ref="listWrap">
<div class="content" :style="contentStyle">
<div class="item" v-for="(item, index) in list"
:key="index" :style="item.style">
{{item.content}}
</div>
</div>
</div>
Corresponding css
*{
padding:0px;
margin: 0px;
}
#app {
width:300px;
border: 1px solid #e5e5e5;
}
/* The outer container gives a fixed visual height , And the settings can scroll */
.vitual-list-wrap {
position: relative;
height: 800px;
overflow-y: auto;
}
/* The area of the real container */
.content {
position: relative;
}
/* Fixed height of each element */
.item {
height: 60px;
padding: 10px 5px;
border-bottom: 1px solid #111;
position: absolute;
left:0;
right: 0;
line-height: 60px;
}
From the corresponding page structure and css Our thinking is roughly like this
- Determine the fixed height of the outer layer , And set the vertical scroll bar
- Relative positioning of real container settings , And dynamically set the height of a loading container according to the displayed total
- Set absolute positioning for each element , And it is a fixed height
With the corresponding setting structure , Because each of our elements is absolutely positioned , So our current thinking is :
1、 Determine the visible area item The number of bars displayed limit
2、 Current position of sliding up Start bit And Last position , Determine the range of display elements
3、 Determine the top, When sliding up , Determine the current location and the location index of the last element , According to the current position and the last element position , Rendering Visual area
The specific logic code is as follows
<div id="app">
<h3> Virtual list </h3>
<div class="vitual-list-wrap" ref="listWrap">
<div class="content" :style="contentStyle">
<div class="item" v-for="(item, index) in list"
:key="index" :style="item.style">
{{item.content}}
</div>
</div>
</div>
</div>
<!-- introduce vue3 Component library -->
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.33/vue.global.min.js"></script>
<script src="./index.js"></script>
Let's see index.js
// index.js
const { createApp, reactive, toRefs, computed, onMounted, ref } = Vue;
const vm = createApp({
setup() {
const listWrap = ref(null);
const viewData = reactive({
list: [],
total: 1000, // The total number of data
height: 600, // The height of the viewing area
rowHeight: 60, // Every one of them item Height
startIndex: 0, // initial position
endIndex: 0, // End position
timer: false,
bufferSize: 5 // Make a buffer
});
const contentStyle = computed(() => {
return {
height: `${viewData.total * viewData.rowHeight}px`,
position: 'relative',
}
});
// todo Set up the data
const renderData = () => {
viewData.list = [];
const {rowHeight, height, startIndex, total, bufferSize} = viewData;
// Of the current viewing area row Number of pieces
const limit = Math.ceil(height/rowHeight);
console.log(limit, '=limit');
// The last position of the visible area
viewData.endIndex = Math.min(startIndex + limit + bufferSize, total -1);
for (let i=startIndex; i<viewData.endIndex; i++) {
viewData.list.push({
content: i,
style: {
top: `${i * rowHeight}px`
}
})
}
}
// todo Monitor rolling , Set up statIndex And endIndex
const handleScroll = (callback) => {
// console.log(listWrap.value)
listWrap.value && listWrap.value.addEventListener('scroll', (e) => {
if (this.timer) {
return;
}
const { rowHeight, startIndex, bufferSize } = viewData;
const { scrollTop } = e.target;
// Calculate the current scroll position , Get the starting position of the current start
const currentIndex = Math.floor(scrollTop / rowHeight);
viewData.timer = true;
// console.log(startIndex, currentIndex);
// Do a simple throttling treatment
setTimeout(() => {
viewData.timer = false;
// If the sliding position is not the current position
if (currentIndex !== startIndex) {
viewData.startIndex = Math.max(currentIndex - bufferSize, 0);
callback();
}
}, 500)
})
}
onMounted(() => {
renderData();
handleScroll(renderData);
})
return {
...toRefs(viewData),
contentStyle,
renderData,
listWrap
}
},
})
vm.mount('#app')
Take a look at the page , already ok 了 , Each up slide will only load the corresponding data at a fixed height
Notice that we are css There's a piece of code like this in
#app {
width:300px;
border: 1px solid #e5e5e5;
opacity: 0;
}
...
[data-v-app]{
opacity: 1 !important;
}
This processing is mainly used to interpolate expressions when they are not rendered , Let users not see the content of the template before rendering . If you don't hide it first , Then there will be interpolation expressions when the page opens ,vue One is provided in v-cloak, But it doesn't seem to work here , stay vue2 Medium is ok .
This is a very simple virtual list implementation , Understand the implementation idea behind the virtual list , More on that vue-virtual-scroller[1] And react-virtualized[2] Implementation of source code , For specific application examples, please refer to a previous article on partial application The test script crashed the page .
summary
- Understand what virtual lists are , In big data rendering , Select a visual area to display the corresponding data
- The principle behind the implementation of virtual lists , The outermost layer is given a fixed height , Then set the vertical
Y Axisrolling , Then the parent of each element sets the relative positioning , Set the height of the real display data , according toitemFixed height (rowHeight), According to the visual area androwHeightCalculate displayablelimitnumber . - When the scroll bar slides up , Calculate the rolling distance
scrollTop, adoptcurrentIndex = Math.floor(scrollTop/rowHeight)Calculate the current starting index - according to
endIndex = Math.min(currentIndex+limit, total-1)Calculate the last index that can be displayed - According to the
startIndexAnd end positionendIndex, according tostartIndexAndendIndexRender the visual area - Sample code of this article code example[3]
- This article refers to related articles How to realize a highly adaptive virtual list [4], This is a
reactVersion of
Reference material
[1] vue-virtual-scroller: https://github.com/Akryum/vue-virtual-scroller
[2] react-virtualized: https://github.com/bvaughn/react-virtualized
[3] code example: https://github.com/maicFir/lessonNote/tree/master/javascript/08-%E8%99%9A%E6%8B%9F%E5%88%97%E8%A1%A8
[4] How to realize a highly adaptive virtual list : https://juejin.cn/post/6948011958075392036
边栏推荐
- 数据库系统原理与应用教程(061)—— MySQL 练习题:操作题 21-31(五)
- POJ3275 Ranking the Cows题解
- 使用 Fail2ban 保护 Web 服务器免受 DDoS 攻击
- strcmp、strstr、memcpy、memmove的实现
- Istio IV fault injection and link tracking
- 了解BFC特性,轻松实现自适应布局
- 掌握常见的几种排序-选择排序
- 数据库系统原理与应用教程(059)—— MySQL 练习题:操作题 1-10(三)
- Tutorial on the principle and application of database system (062) -- MySQL exercise questions: operation questions 32-38 (6)
- 使用 IPtables 进行 DDoS 保护
猜你喜欢

在 Kubernetes 中部署应用交付服务(第 1 部分)

30 day question brushing training (I)

How to play a data mining game entry Edition

Better and more modern terminal tools than xshell!

30 day question brushing plan (III)

SLAM论文合集

Deploy application delivery services in kubernetes (Part 1)

Operator3-设计一个operator

7. Dependency injection

111. SAP UI5 FileUploader 控件实现本地文件上传,接收服务器端的响应时遇到跨域访问错误
随机推荐
Generation of tables and contingency tables (cross tables) of R language factor data: use the summary function to analyze the list, view the chi square test results, and judge whether the two factor v
DXF reading and writing: align the calculation of the position of the dimension text in the middle and above
【飞控开发基础教程7】疯壳·开源编队无人机-SPI(气压计数据获取)
Analyzing the principle of DNS resolution in kubernetes cluster
30天刷题计划(三)
R language ggplot2 visualization: use the ggviolin function of ggpubr package to visualize violin diagrams, set the palette parameter, and customize the border colors of violin diagrams at different l
DXF读写:对齐尺寸标注文字居中、上方的位置计算
Poj3259 wormhole solution
最强分布式锁工具:Redisson
UVA11175有向图D和E From D to E and Back题解
UVA1599理想路径题解
SAP UI5 FileUploader 控件实现本地文件上传,接收服务器端的响应时遇到跨域访问错误的试读版
Denial of service DDoS Attacks
My friend sent me some interview questions
Implementation of StrCmp, strstr, memcpy, memmove
R语言使用lm函数构建线性回归模型、使用subset函数指定对于数据集的子集构建回归模型(使用floor函数和length函数选择数据前部分构建回归模型)
R language Visual scatter diagram, geom using ggrep package_ text_ The repl function avoids overlapping labels between data points (add labels to specific areas of the visual image using the parameter
不用Swagger,那我用啥?
Remember to use pdfbox once to parse PDF and obtain the key data of PDF
Cool operation preheating! Code to achieve small planet effect