vue3.0 封装通用分页组件

目的:封装一个统一的分页组件。
分页的本质:分批次查询数据(基于页码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"/>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值