Vue2简单封装一个分页组件

<template>
  <div class="pagination">
    <ul @click="currentChange($event)">
      <!-- 上一页 -->
      <li :class="['preButton', currentPage === 1 ? 'disabled' : '']">&lt;</li>
      <!-- 第一页 -->
      <li
        :class="[1 == currentPage ? 'active' : '', 'page']"
        v-if="pageCount > 0"
      >
        1
      </li>
      <li v-if="showPrevMore">...</li>
      <!-- 中间页 -->
      <li
        v-for="item in showPage"
        :class="[item == currentPage ? 'active' : '', 'page']"
      >
        {{ item }}
      </li>
      <li v-if="showNextMore">...</li>
      <!-- 最后一页 -->
      <li
        :class="[pageCount == currentPage ? 'active' : '', 'page']"
        v-if="pageCount > 1"
      >
        {{ Number(pageCount) }}
      </li>
      <!-- 下一页 -->
      <li :class="['nextButton', currentPage === pageCount ? 'disabled' : '']">
        &gt;
      </li>
      <!-- 总共 -->
      <li class="total"><span>{{ total }}</span
        ></li>

      <select
        name="limit"
        id="limit"
        class="pageSizes-li"
        v-model="limit"
        @change="limitChangeHnadler"
      >
        <option
          v-for="item in pageSizes"
          :value="item"
          :label="item + '页/条'"
        ></option>
      </select>
    </ul>
  </div>
</template>

<script>
import { propsType } from "./constant";
import { isChangeCurrentPage } from "./utils";
export default {
  name: "YuPagination",
  props: propsType,
  data() {
    return {
      limit: this.pageSizes[0],
      showPrevMore: false,
      showNextMore: false,
    };
  },

  computed: {
    pageCount() {
      return Math.ceil(this.total / this.pageSize);
    },
    showPage() {
      const array = [],
        pagerCount = this.pagerCount, //7
        halfPagerCount = (pagerCount - 1) / 2, //3
        currentPage = Number(this.currentPage), //当前页
        pageCount = Number(this.pageCount); //总页数
      let showPrevMore = false,
        showNextMore = false;
      if (pageCount > pagerCount) {//总页数大于7的时候可以显示...
        if (currentPage > pagerCount - halfPagerCount) {//当前页>7-3的时候显示左边...
          console.log('显示左边',currentPage,'currentPage',currentPage > pagerCount - halfPagerCount,);
          showPrevMore = true;
        }
        if (currentPage < pageCount - halfPagerCount) {//当前页<总页数-3的时候显示右边...
          console.log('显示右边',currentPage,'currentPage',currentPage < pageCount - halfPagerCount);
          showNextMore = true;
        }
      }
      if (showPrevMore && !showNextMore) {//左边显示更多说明右边到结尾
        const startPage = pageCount - (pagerCount - 2);
        for (let i = startPage; i < pageCount; i++) {
          array.push(i);
        }
      } else if (!showPrevMore && showNextMore) {//右边显示更多,左边到头
        for (let i = 2; i < pagerCount; i++) {
          array.push(i);
        }
      } else if (showPrevMore && showNextMore) {//中间显示5个
        const offset = Math.floor(pagerCount / 2) - 1;
        for (let i = currentPage - offset; i <= currentPage + offset; i++) {
          array.push(i);
        }
      } else {//页数比较少直接渲染全部页
        for (let i = 2; i < pageCount; i++) {
          array.push(i);
        }
      }
      this.showPrevMore = showPrevMore;
      this.showNextMore = showNextMore;
      return array;
    },
  },
  methods: {
    limitChangeHnadler() {
      this.$emit("update:pageSize", this.limit);
      this.$emit("pageSizeChange");
    },
    currentChange(e) {
      if (isChangeCurrentPage(e, this.disabled))
        this.clickPageHandler(e.target.textContent);
      if (e.target.className == "preButton") this.preClickHandler();
      else if (e.target.className == "nextButton") this.nextClickHandler();
    },
    clickPageHandler(value) {
      this.$emit("update:currentPage", parseInt(value));
      this.$emit("currentChange");
    },
    //上一页
    preClickHandler() {
      if (this.currentPage > 1) {
        this.$emit("update:currentPage", this.currentPage - 1);
        this.preClick();
      }
    },
    //下一页
    nextClickHandler() {
      if (this.currentPage < this.pageCount) {
        this.$emit("update:currentPage", this.currentPage + 1);
        this.nextClick();
      }
    },
  },
};
</script>

<style type="text/css" scoped>
.pagination {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  width: 100%;
}
ul {
  display: flex;
  justify-content: space-around;
  margin: 0 100px;
}
li {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  line-height: 40px;
  list-style: none;
  margin: 0 5px;
  border: 1px solid #eee;
}
ul li:last-child {
  width: auto;
  height: auto;
  border: none;
}
ul li:last-child span {
  margin: 0 5px;
}
.active {
  color: orange;
  background-color: #333;
}
li:hover {
  cursor: pointer;
}
.total,
.pageSizes-li {
  margin: 0 15px;
  font-size: 12px;
  border: none;
}
.pageSizes-li {
  border-radius: 5px;
  padding: 0 20px;
  border: 1px solid rgb(64, 158, 255) !important;
  position: relative;
}
.pageSizes {
  position: absolute;
  width: 100%;

  top: 0;
  left: 0;
  background-color: #eee;
  z-index: 1;
  border: 1px solid #fff;
}
.disabled {
  background-color: #eee;
}
</style>
//父组件
<YuPagination 
    :currentPage.sync='currentPage'
    :total.sync='total'
    :pageSize.sync='pageSize'
    :pageSizes='pageSizes'
    @currentChange='changeCurrentPage'
    @pageSizeChange='pageSizeChange'
    />
  data() {
    return {
      currentPage:1,
      total:200,
      pageSize:10,
      pageSizes:[10,15,20,30]
    };
  },
  methods: {
    changeCurrentPage(){
      console.log(this.currentPage);
    },
    pageSizeChange(){
      console.log(this.pageSize);
    },
  }
    
//props接收属性
export const propsType = {
    total: {
        type: Number,
        default:30,
    },
    currentPage: {
        type: Number,
        default:1
    },
    pageSize: {
        type: Number,
        default:10
    },
    pageSizes: {
        type: Array,
        default:()=>[10,15,20,25]
    },
    disabled: {
        type: Boolean,
        default:false
    },
    preClick: {
        type: Function,
        default:()=>{}
    },
    nextClick: {
        type: Function,
        default:()=>{}
    },
    pagerCount: {
        type: Number,
        default:7
    }
}

实现的功能

  1. 切换页数时触发的用户传入事件
  2. 改变页码限制时触发用户传入的事件
  3. 点击前一页按钮和后一页按钮触发props传入的事件

效果展示

在这里插入图片描述

后续可以优化的

  1. 抽离CSS
  2. 让用户传入一些属性来动态渲染分页组件的样式:例如大小,颜色
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大鲤余

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值