美文网首页学习前端开发那些事儿
手写一个简易的vue分页器(一)

手写一个简易的vue分页器(一)

作者: 踏莎行 | 来源:发表于2021-06-09 14:08 被阅读0次

    先看一下效果


    Snipaste_2021-06-04_10-12-54.png

    样式分析

    • 一个分页器首先需要上一页,下一页,中间的页码,以及数据的总条数
    • 当前页高亮显示,还有不能点击的按钮,能点击的按钮

    静态样式 Pageination.vue

    <template>
      <div class="pageination">
        <button>上一页</button>
        <button>1</button>
        <button>...</button>
        <button class="disabled">3</button>
        <button>4</button>
        <button class="active">5</button>
        <button>6</button>
        <button>7</button>
        <button>8</button>
        <button>...</button>
        <button class="disabled">12</button>
        <button>下一页</button>
        <button class="disabled">共 20 条</button>
      </div>
    </template>
    
    <script>
    export default {
      name: "Pageination"
    </script>
    
    <style lang="less" scoped>
    .pageination {
      button {
        margin: 0 5px;
        background-color: #f4f4f5;
        color: #606266;
        outline: none;
        border-radius: 2px;
        pad: 0 4px;
        vertical-align: top;
        display: inline-block;
        font-size: 13px;
        min-width: 35.5px;
        height: 28px;
        line-height: 28px;
        cursor: pointer;
        box-sizing: border-box;
        text-align: center;
        border: 0;
    
        &.active {
          background-color: #409eff;
          color: #fff;
          cursor: not-allowed;
        }
    
        &.disabled {
          cursor: not-allowed;
          color: #ccc;
        }
      }
    }
    </style>
    

    使用

    • 注册组件
    Vue.component(Pageination.name, Pageination)
    
    • 使用
      通过父组件向分页组件传值,这里使用props,父组件需要向分页组件传入响应的数据
    <Pagination
      :currentPage="xxx"
      :total="xxx"
      :pageSize="xxx"
      :showPageNo="xxx"
      @currentChange="xxxxxx"
    ></Pagination>
    /**
     * currentPage: 当前页码,就是当前页面是第几页
     * total: 总数量,比如搜索出的结果一共有多少条
     * pageSize: 每一页显示的数据条数
     * showPageNo: 连续页码数
     * currentChange:页码发生变化时触发的事件
     */
    

    showPageNo: 连续页码的意思是,当我们分页过多时,全部显示出来就会显得不好看,取值为奇数。假如连续页码取值为3,当前页是4,那么就显示第3,4,5页码,第一页和最后一页保留,其他页使用“...”折叠


    Snipaste_2021-06-04_10-40-24.png
    • 分页组件的props ------> Pageination.vue
    export default {
      props: {
        currentPage: {
          // 限制参数类型
          type: Number, 
          // 设置默认值
          default: 1,
        },
    
        total: {
          type: Number,
          default: 0,
        },
    
        pageSize: {
          type: Number,
          default: 10,
        },
    
        showPageNo: {
          type: Number,
          default: 5,
          // prop自定义验证函数
          // 官网:https://cn.vuejs.org/v2/guide/components-props.html#Prop-%E9%AA%8C%E8%AF%81 
          validator: function (value) {
            return value % 2 === 1;
          },
        },
      }
    }
    

    计算 ----------> Pageination.vue

    有些属性,需要已知的数据进行计算得来,在分页组件中使用计算属性

      data() {
        return {
          // this.currentPage就是props里面传过来的
          myCurrentPage: this.currentPage
        };
      },
    
    computed: {
        // 总页数 = 总数据数 / 每页显示的数据条数
        // 最后结果使用向上取整,因为pageSize 只是每页最大显示的条数,不够整除,余下的数据也应自成一页
        totalPage() {
          const { total, pageSize } = this;
          return Math.ceil(total / pageSize);
        },
        
        // 设置连续页码的起始和结束的页码
        startEnd() {
          // 获取计算依赖项
          const { myCurrentPage, showPageNo, totalPage } = this;
          let start, end;
          /**
           * 起始页码就是用当前页码减去最大连续页码除以2并向下取整的结果。
           * 如:showPageNo=3,当前页是4,那么起始页码就应该是3,4- Math.floor(3/ 2)=4-1=3
           * 当然start是有边界的,当他小于一了就强制变成1
           */
          start = myCurrentPage - Math.floor(showPageNo / 2);
          if(start < 1){
            start = 1
          }
    
          /**
           * 结束页码就可以利用起始页码进行计算
           */
          end = start + showPageNo - 1
    
          /**
           * 结束页码的边界值就是当他超过总页数
           * 如:总页数为10,当前页是9,最大连续页码是5,
           * 这时候算出来的start = 9 - 2 = 7,end = 7 + 5 -1 = 11 > 10, 所以需要修正
           * end修正之后,start和end的间距就不是设置的showPageNo 了,
           * start也要修改,使用end反推start,start = end - showPageNo 这样子多剪了一个1,后面还要加上,同样的,要对边界值判断
           */
          if(end > totalPage){
            // 修改end为totalPage
            end = totalPage
            // reset start
            start = end - showPageNo + 1
            if(start < 1){
              start = 1
            }
          }
          return { start, end };
        },
      },
    

    完整的js程序

    <script>
    export default {
      name: "Pageination",
      props: {
        currentPage: {
          type: Number,
          default: 1,
        },
    
        total: {
          type: Number,
          default: 0,
        },
    
        pageSize: {
          type: Number,
          default: 10,
        },
    
        showPageNo: {
          type: Number,
          default: 5,
          validator: function (value) {
            return value % 2 === 1;
          },
        },
      },
    
      data() {
        return {
          myCurrentPage: this.currentPage,
        };
      },
    
      mounted(){
        console.log(this);
      },
    
      computed: {
        totalPage() {
          const { total, pageSize } = this;
          return Math.ceil(showPageNo);
        },
    
        startEnd() {
          const { myCurrentPage, showPageNo, totalPage } = this;
          let start, end;
          start = myCurrentPage - Math.floor(showPageNo / 2);
          if(start < 1){
            start = 1
          }
    
          end = start + showPageNo - 1
    
          if(end > totalPage){
            end = totalPage
            start = end - showPageNo + 1
            if(start < 1){
              start = 1
            }
          }
          return { start, end };
        },
      },
    };
    </script>
    

    下一节

    相关文章

      网友评论

        本文标题:手写一个简易的vue分页器(一)

        本文链接:https://www.haomeiwen.com/subject/ewyzsltx.html