Vue原生封装分页组件

封装分页组件的本质:
前端:分批次查询(常规的分页基于页码(page)和每页的条数(pagesize))
后端:后端接收到分页参数后,会基于这些参数查询数据库,然后基于数据库进行分页:基于SQL语句(select * from user limit n,m)

大致步骤:

  • 分页基础布局,依赖数据分析。

  • 分页内部逻辑,完成切换效果。

  • 接收外部数据,提供分页事件。

<template>
  <div class="xtx-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: 'XtxPagination',
  props: {
    total: {
      type: Number,
      default: 0
    },
    pagesize: {
      type: Number,
      default: 10
    }
    // 初始默认页码
    // page: {
    //   type: Number,
    //   default: 1
    // }
  },
  setup(props, { emit, attrs }) {
    // 动态计算中间的页码信息
    // 依赖于父组件的total
    // 每页的条数
    // const pagesize = 8
    // 当前页
    const currentPage = ref(attrs.page || 1)
    // 计算总页数(向上取整)
    // 初始值total是0
    // 因为setup只执行一次,这里的pages就不会重新计算
    // 所有,要在计算属性重新计算
    const pages = computed(() => Math.ceil(props.total / props.pagesize))
    const list = computed(() => {
      // 当父组件传递给total发生变化时,计算属性重新计算
      // pages = Math.ceil(props.total / props.pagesize)
      const result = []
      // 总页码在小于等于5;大于5
      if (props.pagesize <= 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">
.xtx-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>

 分页组件封装好啦,支持点击页码切换更新数据功能,点击上一页下一页更新数据功能,只需要使用的父组件传递过来需要的total、pagesize、以及当前页,page

父组件代码

 <XtxPagination @change-page="changePage" :pagesize="reqParams.pageSize" :total="total" :page="1" />

  // 控制页码的变化
    const changePage = page => {
// 更改页码,发送请求
      console.log(page)
      reqParams.page = page
    }

注:

总结:attrs表示父组件传递的属性,但是子组件没有用props接收的属性,这样的属性不是响应式的。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值