目的:封装一个统一的分页组件。
分页的本质:分批次查询数据(基于页码page和每页条数pagesize),后端接收到分页参数后,会基于这些参数查询数据库,然后基于数据库进行分页:基于SQL语句(select * from user limit n, m)
效果图
1.封装组件
src/components/pagination.vue
<!-- 此组件需全局注册使用 -->
<template>
<div class="pagination">
<a href="javascript:;" :class="{disabled:currentPage === 1}" @click="changePage(false)">上一页</a>
<span v-if="currentPage>3">...</span>
<a href="javascript:;" @click="changePage(i)" v-for="i in pageList" :key="i" :class="{active:currentPage===i}">{{i}}</a>
<span v-if="currentPage<pages-2">...</span>
<a href="javascript:;" :class="{disabled:currentPage === pages}" @click="changePage(true)">下一页</a>
</div>
</template>
<script>
import { computed, ref } from 'vue'
export default {
name: 'XtxPagination',
props: {
total: { // 从使用该组件的父组件,传递过来的总条数
type: Number,
default: 0
},
pagesize: { // 从使用该组件的父组件,传递过来的每页数据的条数
type: Number,
default: 10
}
},
setup (props, { emit, attrs }) {
const pages = computed(() => { // 总页数
return Math.ceil(props.total / props.pagesize)
})
// attrs 可以获取到父组件传递过来的数据,且子组件在props中没有接收的
const currentPage = ref(attrs.page || 1) // 当前页码,默认值1或attrs.page
const pageList = computed(() => { // 页码列表
const result = []
if (pages.value <= 5) { // 总页数小于5
for (let i = 1; i <= pages.value; i++) {
result.push(i)
}
} else {
if (currentPage.value <= 3) {
for (let i = 1; i <= 5; i++) {
result.push(i)
}
} else if (currentPage.value >= pages.value - 2) {
for (let i = pages.value - 4; i <= pages.value; i++) {
result.push(i)
}
} else {
for (let i = currentPage.value - 2; i <= currentPage.value + 2; i++) {
result.push(i)
}
}
}
return result
})
// 页码变化的处理函数
const changePage = (type) => {
if (type === false) { // 上一页
if (currentPage.value === 1) return
currentPage.value--
} else if (type === true) { // 下一页
if (currentPage.value === pages.value) return
currentPage.value++
} else { // 页码按钮
currentPage.value = type
}
// 触发父组件内的自定义事件,传递当前页码数据,调用相应的api接口
emit('change-page', currentPage.value)
}
return { pages, currentPage, pageList, changePage }
}
}
</script>
<style scoped lang="less">
.pagination {
display: flex;
justify-content: center;
padding: 30px;
> a {
display: inline-block;
padding: 5px 10px;
border: 1px solid #e4e4e4;
border-radius: 4px;
margin-right: 10px;
&:hover {
color: @xtxColor;
}
&.active {
background: @xtxColor;
color: #fff;
border-color: @xtxColor;
}
&.disabled {
cursor: not-allowed;
opacity: 0.4;
&:hover {
color: #333
}
}
}
> span {
margin-right: 10px;
}
}
</style>
<!-- 分页组件 -->
<pagination :total="total" :pagesize="pagesize" :page="1" @change-page="changePage"/>