分页是每个前端开发者都会遇到的需求,尤其是在展示大量数据时。一个良好的分页设计能够有效提升用户体验,并且提高应用的性能。今天,我将为大家展示如何用 Svelte 开发一个简洁、灵活、功能完备的分页组件,让你在项目中轻松管理分页功能。
一.功能需求概述
我们这次要构建的分页组件具有以下几个核心功能:
-
总条数展示:显示当前数据的总条数,帮助用户了解数据量。
-
每页条数选择:让用户选择每页显示的数据条数,提供灵活的分页方式。
-
页码跳转:允许用户通过点击页码或直接输入目标页码进行跳转。
-
上下页按钮:通过“上一页”和“下一页”按钮来快速翻页。
-
跳转输入框:允许用户通过输入框直接输入页码进行快速跳转。
这些功能不仅增强了交互性,还使得分页组件在使用时更加灵活和人性化。
二.组件代码解析
接下来,我们来看一段用 Svelte 编写的分页组件代码,详细解析每个功能实现。
1. 定义组件的 Props 和基本逻辑
Pagination.svelte
<script>
import { toast } from '@/lib/utils/toast'
import { createEventDispatcher } from 'svelte'
const dispatch = createEventDispatcher()
// 定义组件属性
export let total = 100 // 总条数
export let pageSize = 10 // 每页条数
export let currentPage = 1 // 当前页码
export let pageSizeOptions = [10, 20, 30, 40] // 每页条数选项
let jump_Page
const sign_string = {
left: '<',
right: '>'
}
// 计算总页数
$: totalPages = Math.ceil(total / pageSize)
// 页码选择
function select_change_page(page) {
if (page >= 1 && page <= totalPages) {
dispatch('page_Change', { page })
}
}
// 每页条数选择
function select_change_page_size(event) {
pageSize = +event.target.value
currentPage = 1
dispatch('page_size_Change', { page: currentPage, pageSize })
}
// 跳转页码处理
function hander_jump_Page(page) {
if (page === undefined || page === '' || page === null) {
toast.warning('请输入页码')
jump_Page = ''
return
} else if (page < 1 || page > totalPages) {
toast.error('请输入正确的页码')
jump_Page = ''
return
} else {
currentPage = page
dispatch('page_jump', { page: currentPage })
}
}
</script>
代码解析:
-
组件属性:组件接收四个
props
(total
,pageSize
,currentPage
,pageSizeOptions
),这使得分页功能具备了灵活性和可配置性。 -
计算总页数:通过
Math.ceil(total / pageSize)
来计算总页数。当total
或pageSize
发生变化时,totalPages
会重新计算。 -
页码选择:
select_change_page(page)
方法用于处理用户点击页码按钮的操作,确保用户能够正确跳转到指定的页面。 -
每页条数选择:
select_change_page_size(event)
方法让用户能够选择每页显示的数据条数,并会重置当前页码为 1,防止因每页条数变化而导致数据偏移。 -
跳转页码:
hander_jump_Page(page)
方法确保用户输入合法的页码。如果页码不在合法范围内,组件会给出提示,并防止跳转到无效页。
2. 渲染分页按钮和输入框
<div class="pagination-box">
<!-- 总条数 -->
<div class="pagination-box-total">
<span>总 {total} 条</span>
</div>
<!-- 页码 -->
<div class="pagination-box-currentPage">
<button on:click={() => select_change_page(currentPage - 1)} disabled={currentPage === 1}>
{sign_string.left}
</button>
{#each Array(totalPages).fill(0).map((_, i) => i + 1) as page}
<button class:button-text={currentPage === page} on:click={() => select_change_page(page)}>
{page}
</button>
{/each}
<button on:click={() => select_change_page(currentPage + 1)} disabled={currentPage === totalPages}>
{sign_string.right}
</button>
</div>
<!-- 每页条数选择 -->
<div class="pagination-box-select">
<select on:change={select_change_page_size} bind:value={pageSize}>
{#each pageSizeOptions as size}
<option value={size}>{size} 条/页</option>
{/each}
</select>
</div>
<!-- 跳转页码 -->
<div class="pagination-box-jump">
<span>前往</span>
<div class="pagination-box-jump-input">
<input
type="number"
bind:value={jump_Page}
min="1"
max={totalPages}
on:keydown={e => {
if (e.key === 'Enter') {
hander_jump_Page(jump_Page)
}
}}
/>
</div>
</div>
</div>
功能实现:
-
总条数显示:通过一个简单的
span
标签展示总数据条数,帮助用户快速了解数据量。 -
页码显示:通过
Array(totalPages).fill(0).map((_, i) => i + 1)
动态渲染页码按钮,确保无论数据量有多少,组件都能正确显示所有页码。 -
跳转页码:用户可以通过输入框输入页码并按下“Enter”键来跳转到指定页码。
-
每页条数选择:提供一个下拉框,允许用户选择每页显示的数据条数。每当用户选择新的条数时,
select_change_page_size()
会触发,更新组件的状态。
3. 样式设计
.pagination-box {
padding: 7px;
height: 40px;
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
}
.pagination-box-total {
display: flex;
margin-right: 10px;
}
.pagination-box-currentPage {
display: flex;
align-items: center;
gap: 5px;
}
.pagination-box-select {
background-color: #f2f3f5;
height: 32px;
width: 90px;
padding: 0 5px;
display: flex;
margin-right: 10px;
align-items: center;
}
.pagination-box-jump {
display: flex;
align-items: center;
}
优化细节:
-
禁用按钮:通过
disabled={currentPage === 1}
和disabled={currentPage === totalPages}
控制“上一页”和“下一页”按钮的禁用状态,避免用户点击无效按钮。 -
当前页码高亮:通过
class:button-text={currentPage === page}
对当前页码按钮应用高亮效果,帮助用户明确当前所处页码。 -
输入框格式化:对输入框使用了
min="1"
和max={totalPages}
限制输入的页码范围,确保跳转的页码有效。
三.总结:
这个分页组件简单、灵活,功能完备,能够轻松满足大部分分页需求。而且,Svelte 的响应式机制使得组件的更新变得非常高效,极大提高了性能和用户体验。