Vuetify系列组件是我刚学习使用Vue时比较熟悉的一个组件库。这个库遵循Material Design的设计风格,简洁大气,很对我的胃口。
这次有个小项目,决定拾起来用下,发现Vuetify 已经更新到第三版了。用了Vite和pina。
这个项目里面涉及到一个分页表格的显示。
所谓分页显示,是指前端要渲染显示一个不定长的数组,由于这个数组可能很长,比如1000,全部显示在一页不好看也难控制。所以拆分成比如50页,每页20个。这样的行为就叫分页。
所以分页是由表格和分页器组成。表格显示每页中的对象,分页器处理分页和翻页。
一开始我让Chatgpt照着Vuetify3的文档写了一个。结果发现,这是一个前端分页的写法。
前端分页,就是当前端查询数组时,后端一股脑返回所有的结果,前端接收到所有的结果后,分成几页来显示。这样的好处是写法相对简单,后端不需要实现分页,前端拿到了所有的结果,只需要将结果分块,切换页码时更换显示内容,不需要再次查询,会显得很流畅。
但是代价也是很大的,首先每次请求都是全部数据,这样通信开销大。不能起到分页的省流作用。其次前端分页,数量大的时候就会存在性能问题。
所以保守的做法,肯定是后端实现分页功能,前端创建分页查询请求。这样用户翻页时,构造不同的请求参数,拿到不同的结果,最后返回给表格渲染。
所以后端分页前端需要关注以下内容:
- Total: 所有数据量
- Page: 当前页
- PageSize:每页数量,既是分页的单位,也是表格每页显示的单位
- TotalPages: 页面总数,用于分页器切换。这个数据可以由后端提供,也可以在前端根据Total / PageSize 取整估算。
结果我最后就是在第4点翻车了,代码如下:
// 正确的写法
Math.ceil(this.totalItems / this.pageSize)
// 错误的写法
Math.ceil(this.totalItems , this.pageSize)
充分说明代码还是复制比手抄好,抄着抄着抄错了。
Vuetify 3提供了Table和Pagination组件。
示例如下
<template>
<v-data-table
v-model:page="page"
:headers="headers"
:items="desserts"
:items-per-page="itemsPerPage"
>
<template v-slot:top>
<v-text-field
:model-value="itemsPerPage"
class="pa-2"
label="Items per page"
max="15"
min="-1"
type="number"
hide-details
@update:model-value="itemsPerPage = parseInt($event, 10)"
></v-text-field>
</template>
<template v-slot:bottom>
<div class="text-center pt-2">
<v-pagination
v-model="page"
:length="pageCount"
></v-pagination>
</div>
</template>
</v-data-table>
</template>
不过其实我有点没看董,里面既有双向绑定v-model,并且table和pagination都有,然后输入框那里,又用了model-value和update事件。
出吃之外还要处理一些逻辑,比如修改页码后,需要监听页码修改,触发请求接口,而pageSize更改后,原来的页码可能失效,我的做法是将page修改为第一页。
发表回复