Spring Boot+Vue 实现后端分页前端批量展示
前言
在开发前端项目时,当我们需要展示的数据量过多从而无法一次性展示完的时候我们就会采用分页的方式,但是很多小白基本上都是使用element-UI或者其他方式实现前端分页,前端分页的弊端在于需要一次性将所有数据全部取出,当我们需要展示的内容基数过大时,如果一次性取出就会导致前端渲染缓慢,影响用户使用体验。而后端分页,前端批量展示的优势在于当我需要展示某一页的内容时,我仅需去后端取出该页面的内容即可。这样一来无论你的数据量基数多大,每一页我仅需去取少量的数据,防止前端因数据量过大导致渲染缓慢。关于这部分内容我在网上也查阅过相关资料,很多都是使用现成框架,其实自己实现也不难,今天我就来教大家如何简单的实现后端分页,前端批量展示。
实现步骤
1.PageBean工具类
这个工具类的作用是当我们传入 四个参数(当前页,每页显示的总条数,总条数,需要分页的所有数据),它会去帮我们计算出总页数,开始索引,结束索引以及分页结果。PageBean完整代码如下:
import java.util.ArrayList;
import java.util.List;
/**
* 分页bean 通用各种类型的数据
*/
public class PageBean<T> {
// 当前页
private Integer currentPage = 1;
// 每页显示的总条数
private Integer pageSize = 10;
// 总条数
private Integer totalNum;
// 总页数
private Integer totalPage;
// 开始索引
private Integer startIndex;
// 结束索引
private Integer endIndex;
// 所有的数据
private List<T> items;
// 分页结果
private List<T> pagebeanitems = new ArrayList<>();
// 用于计算所需参数的方法
public void setPageBean(Integer currentPage, Integer pageSize, Integer totalNum,List<T> list) {
// 当前页
this.currentPage = currentPage;
// 每页显示条数
this.pageSize = pageSize;
// 总数
this.totalNum = totalNum;
// 所有数据
this.items = list;
// 总页数
this.totalPage = (int)(Math.ceil(totalNum / (pageSize * 1.0)));
// 开始索引
this.startIndex = (currentPage-1) * pageSize;
// 结束索引
this.endIndex = (currentPage == totalPage) ? totalNum -1 : (currentPage * pageSize) - 1;
}
// 获取分页的结果
public List<T> getPageBean() {
for(int i = startIndex; i <= endIndex; i++){
pagebeanitems.add(items.get(i));
}
return this.pagebeanitems;
}
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotalNum() {
return totalNum;
}
public void setTotalNum(Integer totalNum) {
this.totalNum = totalNum;
}
public Integer getTotalPage() {
return totalPage;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public Integer getStartIndex() {
return startIndex;
}
public void setStartIndex(Integer startIndex) {
this.startIndex = startIndex;
}
public List<T> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
}
2.PageBeanResult类
这个类是用来存储以及给前端返回分页结果的,完整代码如下:
import java.util.List;
public class PageBeanResult<T> {
// 获取的分页数据
private List<T> items;
// 数据总数,方便前端提前展示所有页码
private int totalnum;
public int getTotalnum() {
return totalnum;
}
public List<T> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
public void setTotalnum(int totalnum) {
this.totalnum = totalnum;
}
}
3.Controller调用
在写完工具类之后我们不可能放着不用,总要让它为我们做点事的嘛,因此我们仅需在controller里面对其进行调用即可,调用代码如下:
@CrossOrigin
@PostMapping(value = "api/getpagebean")
@ResponseBody
public PageBeanResult<Article> getPagebean(@RequestBody Map<String,Integer> PageNews) {
Map<String,Integer> pageMap = PageNews;
PageBean<Article> entity = new PageBean();
List<Article> articleList = articleService.findByState(1);
entity.setPageBean(pageMap.get("currentPage"),pageMap.get("pageSize"),articleList.size(),articleList);
List<Article> Beanlist = entity.getPageBean();
PageBeanResult<Article> pageBeanResult = new PageBeanResult<>();
pageBeanResult.setItems(Beanlist);
pageBeanResult.setTotalnum(articleList.size());
return pageBeanResult;
}
这里我对代码进行解释下,防止有些小白看不明白,Article是我定义的一个文章实体类,articleService.findByState()这个方法是用来寻找出已发表的所有文章,这里替换成你们自己的实体类和查找方法就行了。然后我从前端上传了两个参数值,分别是当前页:currentPage和每页显示的总条数pageSize,因此使用了pageMap.get(“currentPage”)和pageMap.get(“pageSize”)来接收。到此后端功能就全部实现了,接下来我们来看看Vue前端的代码实现。
4.前端批量展示
批量展示就是说,比如我一共有100条数据,第一页我只展示10条,那我就去后端取0-9这十条数据,当我点击第二页我就去后端取出10-19这十条数据,其他页以此类推,因此不管你数据量基数多大,我每页只取十条,而不是一次性取出,因此不会出现渲染慢的情况。前端实现代码如下:
<template>
<div class="auditingpage">
<div class="auditing_content_top">
<el-table :data="articles" border stripe>
<el-table-column label="文章编号" prop="id" width="100px"></el-table-column>
<el-table-column label="文章名称" prop="course_title" width="299px">
<template slot-scope="scope">
<el-link target="_blank" :underline="false" @click="toCourse(scope.row.id)">{{scope.row.course_title}}</el-link>
</template>
</el-table-column>
<el-table-column label="分类专栏" prop="classify" width="115px"></el-table-column>
<el-table-column label="发布时间" prop="time" width="150px"></el-table-column>
<el-table-column label="作者" prop="name" width="120px"></el-table-column>
<el-table-column label="审核" width="175px">
<template slot-scope="scope">
<el-button style="float:left" type="success" @click="checkOK(scope.row)">通过</el-button>
<el-button style="float:left" type="danger" @click="goBack(scope.row)">驳回</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="auditing_content_bottom" v-if="totalnum > pagesize">
<el-pagination style="margin-top:10px" @size-change="handleSizeChange" @current-change="handleCurrentChange"
:page-size="pagesize"
background
:pager-count="pagesize"
layout="prev, pager, next"
:total="totalnum">
</el-pagination>
</div>
</div>
</template>
<script>
export default {
name: 'auditingpage',
data () {
return {
currentPage: 1, // 初始页
pagesize: 6, // 每页的数据
totalnum: 0, // 总数
articles: [] // 文章数组
}
},
mounted: function () {
this.getPageBeans()
},
created () {
},
watch: {
},
methods: {
getPageBeans () {
var that = this
that.$axios.post('/getpagebean', {
currentPage: this.currentPage,
pageSize: this.pagesize
}).then(resp => {
if (resp && resp.status === 200) {
that.totalnum = resp.data.totalnum
that.articles = []
for (var i = 0; i < resp.data.items.length; i++) {
that.articles.push({
course_title: resp.data.items[i].title,
name: resp.data.items[i].author,
time: resp.data.items[i].time
classify: resp.data.items[i].classify,
id: resp.data.items[i].id
})
}
// console.log('查看下:', that.articles)
} else {
that.$message({showClose: true, message: '获取文章出了点小问题!', type: 'error'})
}
})
},
// 初始页currentPage、初始每页数据数pagesize和数据data
handleSizeChange: function (size) {
this.pagesize = size
// console.log(this.pagesize) // 每页下拉显示数据
},
handleCurrentChange: function (currentPage) {
this.currentPage = currentPage
this.getPageBeans()
// console.log(this.currentPage) // 点击第几页
},
checkOK (row) {
},
goBack (row) {
}
}
}
</script>