Vue3自己封装一个分页组件
背景在浏览列表类型的数据的时候,如果数据比较多一次性全部请求会出现性能损耗以及加载延迟等问题,那么此时分页组件就起到了关键作用,它可以只请求一部分数据,也不会占用太多的页面空间,想看别的数据可以通过页码的改变来发起请求,刷新页面数据。为什么要封装分页组件分页功能使用场景较多,故考虑封装为全局组件自己封装成本较低,需要什么功能就添加什么功能相对使用现成组件库,自己封装代码体积可控如何封装分页组件第一
·
目录
背景
在浏览列表类型的数据的时候,如果数据比较多一次性全部请求会出现性能损耗以及加载延迟等问题,那么此时分页组件就起到了关键作用,它可以只请求一部分数据,也不会占用太多的页面空间,想看别的数据可以通过页码的改变来发起请求,刷新页面数据。
为什么要封装分页组件
- 分页功能使用场景较多,故考虑封装为全局组件
- 自己封装成本较低,需要什么功能就添加什么功能
- 相对使用现成组件库,自己封装代码体积可控
如何封装分页组件
第一步组件所需参数:
total
属性 :用来传递数据总条数
pagesize
属性 :每页展示几条数据
currentPage
属性 :当前默认页码
change-page
事件 :页码改变时触发的事件,参数为当前页码
第二步代码
先在components里面封装一个组件
<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>
然后在.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>
效果演示
更多推荐
所有评论(0)