前言
分页功能相信大家经常见到,不管是前台页面还是后台管理系统,只要涉及到数据较多的时候,就会用到分页组件。本文将带你自己封装一个分页组件,事不宜迟,开整~
一、为什么封装?
- 分页功能使用场景较多,故考虑封装为全局组件
- 自己封装成本较低,需要什么功能就添加什么功能
- 相对使用现成组件库,自己封装代码体积可控
二、如何封装?
1. 封装
和之前文章一样的步骤,src/components
文件夹下新建my-pagination.vue
文件
代码如下(示例):
<template>
<div class="my-pagination">
<a @click='changePage(false)' href="javascript:;" :class="{disabled: currentPage===1}">上一页</a>
<span v-if='currentPage > 3'>...</span>
<a @click='changePage(item)' href="javascript:;" :class='{active: currentPage===item}' v-for='item in list' :key='item'>{{item}}</a>
<span v-if='currentPage < pages - 2'>...</span>
<a @click='changePage(true)' href="javascript:;" :class='{disabled: currentPage===pages}'>下一页</a>
</div>
</template>
<script>
import { computed, ref } from 'vue'
export default {
name: 'MyPagination',
props: {
total: {
type: Number,
default: 80
},
pagesize: {
type: Number,
default: 10
}
// 默认初始页码
// page: {
// type: Number,
// default: 1
// }
},
setup (props, { emit, attrs }) {
// attrs表示父组件传递的属性,但是props没有接收的属性,这种属性不是响应式的
// 动态计算中期的页码信息
// 每页的条数
// const pagesize = 8
// 总页数
const pages = computed(() => Math.ceil(props.total / props.pagesize))
// 当前页码
// console.log(attrs.page)
const currentPage = ref(attrs.page || 1)
// 动态计算页码列表
const list = computed(() => {
// 当父组件传递total的值发生变化时,计算属性会重新计算
// pages = Math.ceil(props.total / props.pagesize)
const result = []
// 总页码小于等于5;大于5
if (pages.value <= 5) {
// 总页码小于等于5的情况
for (let i = 1; i <= pages.value; i++) {
result.push(i)
}
} else {
// 总页码大于5
if (currentPage.value <= 2) {
// 左侧临界值
for (let i = 1; i <= 5; i++) {
result.push(i)
}
} else if (currentPage.value >= pages.value - 1) {
// 右侧临界值
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
if (currentPage.value > 1) {
currentPage.value -= 1
}
} else if (type === true) {
// 下一页
// 页面是最后页时,禁止点击操作
if (currentPage.value === pages.value) return
if (currentPage.value < pages.value) {
currentPage.value += 1
}
} else {
// 点击页码
currentPage.value = type
}
emit('change-page', currentPage.value)
}
return { list, currentPage, pages, changePage }
}
}
</script>
<style scoped lang="less">
.my-pagination {
display: flex;
justify-content: center;
padding: 30px;
> a {
display: inline-block;
padding: 5px 10px;
text-decoration: none;
color: #666;
border: 1px solid #e4e4e4;
border-radius: 4px;
margin-right: 10px;
&:hover {
color: #27ba9b;
}
&.active {
background: #27ba9b;
color: #fff;
border-color: #27ba9b;
}
&.disabled {
cursor: not-allowed;
opacity: 0.4;
&:hover {
color: #333;
}
}
}
> span {
margin-right: 10px;
}
}
</style>
2. 使用
在任意.vue
结尾文件中使用
代码如下(示例): 这里使用固定数据模拟一下
<template>
<div class="home-container">
<MyPagination @change-page='changePage' :pagesize='10' :total='80' :page='1' />
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
name: 'App',
setup () {
// 筛选条件准备
const reqParams = reactive({
// 当前页码
page: 1,
// 每页的条数
pageSize: 10
})
// 控制页码的变化
const changePage = (page) => {
// 修改分页参数,重新调用接口即可
// console.log(page)
reqParams.page = page
}
return { changePage }
}
}
</script>
<style lang="less">
.home-container {
margin: 100px auto;
width: 1000px;
height: 100px;
}
</style>
三、效果演示
总结
More haste,lespeed