本篇讲解下vue和springboot结合的项目中,分页前后台如何实现。(前后台交互格式JSON)
本篇需要spring和springboot的基础,就不多讲。
1.springboot
spring中分页相关的几个类和注解
Pageable
@PageableDefault
Page
后台跟数据库交互的使用JPA方式,还用到了JPA多条件查询,不明白了可以查看
1-1.实体类
先介绍介个实体类和用到的工具类
entity实体类
@Entity
@Table(name = "tools_sys", schema = "iworkh_tool")
public class ToolsSysEntity {
@Id
@Column(length = 32, name = "id")
private String id;
@Column(length = 20, name = "sys_name")
private String sysName;
@Column(length = 2, name = "order_num")
private int orderNum = 1;
@Column(name = "visible_flag")
private boolean visibleFlag = true;
@Column(length = 500, name = "description")
private String description;
...省略setter、getter方法...
搜索参数类
public class ToolsSysSearchVo {
private String sysName;
private boolean visibleFlag = true;
private int orderNum = 1;
..省略setter、getter方法...
}
结果返回类
public class ResponseData<T> {
private boolean success;
private int code = 20000;
private String message;
private T data;
...省略setter、getter方法...
}
Response工具类:
public class ResponseUtils {
public static <T> void setSuccessData(ResponseData<T> responseData, T data){
responseData.setSuccess(true);
// 成功状态码返回20000
responseData.setCode(20000);
responseData.setData(data);
}
public static <T> void setIllegalArgsError(ResponseData<T> responseData, String errMsg){
// 非法入参错误状态码返回30000
responseData.setCode(30000);
responseData.setMessage(errMsg);
}
public static <T> void setServerError(ResponseData<T> responseData, String errMsg){
// 服务端错误状态码返回40000
responseData.setCode(40000);
responseData.setMessage(errMsg);
}
}
1-2.dao
@Repository
public interface ToolsSysDao extends PagingAndSortingRepository<ToolsSysEntity, String>,
JpaSpecificationExecutor<ToolsSysEntity> {
}
1-3.service
@Service
public class ToolsSysService extends BaseService {
@Autowired
private ToolsSysDao toolsSysDao;
public Page<ToolsSysEntity> findByPage(ToolsSysSearchVo searchVo, Pageable pageable){
Specification specificationQuery = new Specification<ToolsSysEntity>(){
@Override
public Predicate toPredicate(Root<ToolsSysEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> list = new ArrayList<>();
if (StringUtils.isNoneBlank(searchVo.getSysName())) {
Path<String> sysNamePath = root.get("sysName");
Predicate sysNameLike = criteriaBuilder.like(sysNamePath, "%"+searchVo.getSysName()+"%");
list.add(criteriaBuilder.and(sysNameLike));
}
Predicate[] p = new Predicate[list.size()];
return criteriaBuilder.and(list.toArray(p));
}
};
Page<ToolsSysEntity> pageRows = toolsSysDao.findAll(specificationQuery, pageable);
return pageRows;
}
}
这为了能够大家能够理解,就没有使用lambda表达式和一些简写使用。
这使用了多条件分页查询。这不是本篇重点。本篇重点是vue和spring的controller如何分页交互。所以具体JPA多条件如何使用请查看
1-4.controller
@RestController
@RequestMapping("/api/toolssys")
public class ToolsSysController {
@Autowired
private ToolsSysService toolsSysService;
@PostMapping("/findByPage")
public ResponseData<Page<ToolsSysEntity>> findByPage(@RequestBody ToolsSysSearchVo searchVo,
@PageableDefault(sort = {"orderNum"},direction = Sort.Direction.DESC) Pageable pageable) {
ResponseData<Page<ToolsSysEntity>> result = new ResponseData<>();
Page<ToolsSysEntity> pageData = toolsSysService.findByPage(searchVo, pageable);
ResponseUtils.setSuccessData(result, pageData);
return result;
}
}
这使用
Pageable
来介绍分页参数,并配合@PageableDefault
注解,指定默认的排序或者页数等参数。
返回值是Page
对象,交给前台进行展示
通过查看Pageable
的实现或者@PageableDefault
里值,可以看到rest需要传哪些参数
1-5.rest测试
到这后台部分就已经好了,我们可以使用Postman来测试下
测试url: http://localhost:8080/api/toolssys/findByPage?page=0&size=5
json参数:
{
"sysName": ""
}
2.vue
2-1.api
export function findByPage(data, pageInfo) {
return request({
url: `/toolssys/findByPage?page=${pageInfo.curPage - 1}&size=${pageInfo.pageSize}`,
method: 'post',
data
})
}
vue和java的分页起始值有一点区别
- vue: 从1开始
- java: 从0开始
或者使用params
来指定参数,而不是拼接URL
export function findByPage(data, pageInfo) {
return request({
url: '/toolssys/findByPage',
method: 'post',
params: { page: pageInfo.curPage - 1, size: pageInfo.pageSize },
data
})
}
还是建议这种方式
2-2.使用
vue-element分页控件
<div class="block">
<el-pagination
:current-page="pageInfo.curPage"
:page-sizes="[5, 10, 20, 50]"
:page-size="pageInfo.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageInfo.totalCount"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
js代码调用
<script>
import { findByPage } from '@/api/tools'
export default {
name: 'SysSetting',
data() {
return {
toolsSysSearchInfo: {
sysName: ''
},
pageInfo: {
curPage: 1,
pageSize: 5,
totalCount: 0
},
tableData: []
}
}, methods: {
handleSizeChange(val) {
// console.log(`每页 ${val} 条`)
this.pageInfo.pageSize = val
this.searchToolsSys()
},
handleCurrentChange(val) {
// console.log(`当前页: ${val}`)
this.pageInfo.curPage = val
this.searchToolsSys()
},
searchToolsSys() {
findByPage(this.toolsSysSearchInfo, this.pageInfo).then(response => {
if (response.success) {
this.pageInfo.totalCount = response.data.totalElements
this.tableData = response.data.content
} else {
this.$message({
message: 'search Failed',
type: 'error'
})
}
})
}
}
}
</script>
2-3.结果展示
3.推荐
能读到文章最后,首先得谢谢您对本文的肯定,你的肯定是对博主最大的鼓励。
你觉本文有帮助,那就点个👍
你有疑问,那就留下您的💬
怕把我弄丢了,那就把我⭐
电脑不方便看,那就把发到你📲