最近接到一个需求,pc端中的table 数据不做分页,而是做成滚动条形式,但是table中的数据还是一次显示50条,等这50条滑动到底部后,再去加载50条(有加载效果),以此类推,直到数据全部展示。
值得注意的是: 我的需求是 第一次请求数据就将全部数据都获取到,后期的数据加载实际上是不走后台接口的,是纯前端数据处理
1、首先要确定 加载数据的时机是:table中的滚动条滑动到底部的时候
scrollEvent(event) {
/**
* 需要判断滚动条是否到达table底部,到达底部时才应该加载数据
* $('.d-table .d-table-body')[0].clientHeight 为table的body部分的可视高度
* $('.d-table .d-table-body')[0].scrollHeight 为table的body部分的实际的总高度
* $('.d-table .d-table-body')[0].scrollTop 为table的body部分已滚动了多少高度
* 可以用scrollTop + clientHeight == scrollHeight 判断滚动条是否到达了底部
*/
if($('.d-table .d-table-body')[0].scrollTop + $('.d-table .d-table-body')[0].clientHeight == $('.d-table .d-table-body')[0].scrollHeight){
// 因为我的table 是封装好的,所以下面这个操作是 调用父组件的scrollEvent事件
this.$emit("scrollEvent");
}
},
2、走接口获取到全部数据,将前五十条展示到table中,同时将全部数据存起来
/** 因为 我获取到的数据,做了一些循环处理,所以是push到了一个数据中,
正常可以直接 将获取到的data 赋值给一个数据,我限
*/
// 用于 制造用滚动条 滚动到底部获取数据的效果
if(self.restoreDataViewData.recordResult.length < 50 ){
// 获取数据,将前50条渲染到table 中
self.restoreDataViewData.recordResult.push(cols);
}
//完整数据留存
self.restoreDataViewData.recordResultCopy.push(cols)
3、当滚动到底部后,触发事件,进行下一段50条数据的补充展示
scrollEvent(){
// 这是 全部数据
let copy = this.restoreDataViewData.recordResultCopy
// 这是 当前页面中table的展示数据
let resu = this.restoreDataViewData.recordResult
// 当展示数据和全部数据相同时,不再继续往下走了
if(resu.length == copy.length) return
// 计算 总数据可以分为几个50 ,向上取整
let count = Math.ceil(copy.length / 50 )
// 计算 当前数据可以分为几个50,向上取整
let currentCount = Math.ceil(resu.length / 50)
// 若即将加载的数据 已经为最后一次加载,那么会出现 剩余未加载的数据不足50 这时取实际长度
let leg = currentCount + 1 == count ? copy.length : (currentCount + 1)*50
// 两个数据 对 50 的倍数相等,证明数据全部加载,不往下走了
if(currentCount < count){
// 自己封装的页面loading show
Dynamics365.ShowCover();
/** 加上定时器因为,此次数据加载的数据是已经请求过的,
因此定时器维持loading状态,否则它就只会闪一下,
如果这个地方要走接口,就不必如此 */
var tableT = setTimeout(()=>{
for(var i = currentCount*50; i<= leg - 1 ; i++){
this.restoreDataViewData.recordResult.push(copy[i])
}
// 页面loading hide
Dynamics365.HideCover();
},300)
}
},
滚动条滑动到底部,触发获取数据的事件(类似翻页)
-----补充使用 InfiniteScroll 无限滚动(elementui) 实现上述效果
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>
body {
padding: 20px 100px;
background-color: #F2F6FC;
}
li {
list-style: none;
}
.topWarp {
margin-bottom: 20px;
}
.head-box {
height: 50px;
line-height: 50px;
background-color: #fff;
padding-left: 10px;
border: 1px solid #eee;
border-radius: 5px;
}
.head-box .head-left {
padding-left: 5px;
border-right: 1px solid #eee;
}
.head-box .head-right {
height: 100%;
padding-left: 20px;
}
.demo-table-expand {
font-size: 0;
}
.demo-table-expand label {
width: 90px;
color: #99a9bf;
}
.demo-table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
width: 50%;
}
.expand-box {
height: 300px;
overflow: auto;
}
.expand-box .child-border {
padding: 5px 10px;
border-bottom: 2px solid #eee;
}
.expand-box .child-border .child-col {
padding-bottom: 3px;
}
.scroll-footer {
height: 2px;
margin-top: 20px;
}
</style>
</head>
<body>
<div id="app">
<div class="topWarp">
<el-row class="head-box">
<el-col :span="4" class="head-left">TotalFiles : </el-col>
<el-col :span="20" class="head-right">
{{jsonDateObj.TotalFiles}}
</el-col>
</el-row>
<el-row class="head-box">
<el-col :span="4" class="head-left">ScanLineCount : </el-col>
<el-col :span="20" class="head-right">
{{jsonDateObj.ScanLineCount}}
</el-col>
</el-row>
<el-row class="head-box">
<el-col :span="4" class="head-left">ScanFileCount : </el-col>
<el-col :span="20" class="head-right">
{{jsonDateObj.ScanFileCount}}
</el-col>
</el-row>
</div>
<el-table :data="tableDate" style="width: 100%; margin-top: 10px;" @expand-change="openRow">
<el-table-column type="expand">
<template slot-scope="props">
<div class="expand-box" id="scrollExpand">
<div class="infinite-list-wrapper" style="overflow:auto">
<ul class="list" v-infinite-scroll="load" infinite-scroll-disabled="disabled">
<li v-for="(item,index) in props.row.ReportDetails" class="list-item">
<el-descriptions class="margin-top" :column="3" border>
<template slot="title">
<el-tag type="warning">
数据{{index + 1}}
</el-tag>
</template>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-thumb"></i>
Rule:
</template>
{{item.Rule}}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-thumb"></i>
LineIndex:
</template>
{{item.LineIndex}}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-thumb"></i>
LineCode:
</template>
{{item.LineCode}}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
Ignore:
</template>
<el-tag size="small">
<el-checkbox v-model="item.Ignore"></el-checkbox>
</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
FileFullName:
</template>
{{item.FileFullName}}
</el-descriptions-item>
</el-descriptions>
</li>
</ul>
<p v-if="loading">加载中...</p>
<p v-if="noMore" style="text-align: center;">没有更多了</p>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="Total" prop="Total">
</el-table-column>
<el-table-column label="Rule" prop="Rule">
</el-table-column>
<el-table-column label="Ignore" prop="Ignore">
<template slot-scope="scope">
<el-tag type="success">
<el-checkbox v-model="scope.row.Ignore"></el-checkbox>
</el-tag>
</template>
</el-table-column>
</el-table>
</div>
</body>
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
new Vue({
el: '#app',
data: function () {
return {
loading: false,
count: 10,
currentPage: 1,
currentNum: 10,
currentTableRow: {},
jsonDate:
{
"TotalFiles": 28613,
"ScanLineCount": 0,
"ScanFileCount": 2375,
"RportTypes": [
{
"Total": 0,
"Rule": "None",
"Ignore": false,
"ReportDetails": []
},
{
"Total": 1,
"Rule": "InsecureDeserialization",
"Ignore": false,
"ReportDetails": [
{
"Rule": "InsecureDeserialization",
"LineIndex": 34,
"FileFullName": "C:\\Wor",
"Message": null,
"LineCode": "var sdf = new BinaryFormatter();",
"Ignore": false
}
]
},
{
"Total": 21282,
"Rule": "ExcludeSubFolder",
"Ignore": false,
"ReportDetails": [
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
}, {
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
}, {
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "ExcludeSubFolder",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "BlackList",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "BlackList",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "BlackList",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
},
{
"Rule": "BlackList",
"LineIndex": 0,
"FileFullName": "C:\\Work",
"Message": null,
"LineCode": null,
"Ignore": false
}
]
},
{
"Total": 0,
"Rule": "Password",
"Ignore": false,
"ReportDetails": []
},
{
"Total": 0,
"Rule": "Connection",
"Ignore": false,
"ReportDetails": []
},
{
"Total": 0,
"Rule": "Tls",
"Ignore": false,
"ReportDetails": []
}
]
},
jsonDateObj: {},
tableDate: [],
}
},
created() {
this.jsonDateObj = JSON.parse(JSON.stringify(this.jsonDate));
this.tableDate = this.jsonDateObj.RportTypes;
this.tableDate.forEach((item, i) => {
item.index = i;
item.spliceReportDetails = item.ReportDetails;
})
},
computed: {
noMore() {
let showCount = 0;
this.jsonDateObj.RportTypes.forEach(item => {
if (item.index === this.currentTableRow.index) {
showCount = item.ReportDetails.length;
}
})
let allCount = 1;
allCount = this.currentTableRow.spliceReportDetails.length;
return showCount >= allCount;
},
disabled() {
return this.loading || this.noMore
}
},
methods: {
// table 当前打开 行 的 数据
openRow(row, expandedRows) {
this.currentTableRow = row;
},
load() {
this.loading = true
setTimeout(() => {
this.jsonDateObj.RportTypes.forEach(item => {
if (item.index === this.currentTableRow.index) {
let start = item.ReportDetails.length;
let end = start + this.currentNum;
let slicDate = item.spliceReportDetails.slice(start, end);
item.ReportDetails.push(...slicDate);
}
})
this.tableDate = this.jsonDateObj.RportTypes;
this.loading = false
}, 5000)
}
}
})
</script>
</html>