Pagination 翻页器实现

当数据量过多时,使用分页分解数据html

Pagination 组件主要特色在于:
  • 利用 v-model 方便拓展;
  • 利用 computed 完成内部逻辑解析。

1. 实例

最终效果

代码git

<fat-pagination :total="1000" :page-size="20" :page-count="11" @change="handleChange" />
复制代码

实例地址:Pagination 实例github

代码地址:Github UI-Libraryapp

2. 原理

基本结构很是简单,能够分为前 forwardPaginations 、中 middlePaginations、后 backwardPaginations,三个部分ide

<div class="pagination-wrapper">
    <ul :class="['pagination-inner', { 'has-background': background }]">
        <!-- backward Paginations -->
        <li v-for="item in forwardPaginations" :key="item" :class="['pagination-item', { 'is-active': item === current }]" @click.stop="handleClick({ type: 'select', data: item })" >{{ item }}</li>
      <!-- end -->
      <!-- middle paginations -->
      <template v-if="isForwardBrief && isBackwardBrief">
        <li v-for="item in middlePaginations" :key="item" :class="['pagination-item', { 'is-active': item === current }]" @click.stop="handleClick({ type: 'select', data: item })" >{{ item }}</li>
      </template>
      <!-- end -->
      <!-- backward paginations -->
      <li v-for="item in backwardPaginations" :key="item" :class="['pagination-item', { 'is-active': item === current }]" @click.stop="handleClick({ type: 'select', data: item })" >{{ item }}</li>
      <!-- end -->
    </ul>
</div>
复制代码

forwardPaginations :前向的 Pagination 主要包含两种状态,缩略或者是展开,当 current 的值超出所设定的红框范围时候,就会呈现缩略状。工具

最终效果

也就是依据 paginalNumber > pageCount && current > pageCount - 3 进行判断post

data() {
    return {
        current: 1
    };
},
computed: {
    // 页数
    paginalNumber() {
        const { total, pageSize } = this;
        return Math.ceil(total / pageSize);
    },
    // 前向是否缩略
    isForwardBrief() {
        const { paginalNumber, pageCount, current } = this;
        return paginalNumber > pageCount && current > pageCount - 3;
    }
  }
复制代码

具体的展现的页码 forwardPaginationsui

forwardPaginations() {
    const { pageCount, isForwardBrief, paginalNumber } = this;
    let start = 0;
    let length = paginalNumber <= pageCount
        ? paginalNumber
        : isForwardBrief
        ? 1
        : pageCount;

    return Array.from({ length }, (v, i) => {
        return i + start + 1;
    });
}
复制代码

一样的原理,还有后向页码 backwardPaginationsthis

isBackwardBrief() {
    const { paginalNumber, pageCount, current } = this;
    return paginalNumber > pageCount && current < paginalNumber - 3;
},
backwardPaginations() {
    const { current, pageCount, isBackwardBrief, paginalNumber } = this;
    let start = paginalNumber - (isBackwardBrief ? 1 : pageCount + 1);
    let length = paginalNumber <= pageCount ? 0 : isBackwardBrief ? 1 : pageCount + 1;

    return Array.from({ length }, (v, i) => {
        return i + start + 1;
    });
}
复制代码

当上述的 computed 属性,知足 isBackwardBrief && isForwardBrief 的条件时候,说明当前先后都处于缩略状态,这是须要生成中间的页码spa

生成的规则就是以 current 为中心,左右拓展 offset 个页码。

最终效果
middlePaginations() {
    const { current, pageCount, isForwardBrief, isBackwardBrief } = this;
    const offset = Math.round(pageCount / 2);
    let start = current - offset;

    return Array.from({ length: pageCount }, (v, i) => {
        return i + start + 1;
    });
}
复制代码

处理 v-model

model: {
    prop: "value",
    event: "change"
}
复制代码

为何要实现数据的双向绑定,是由于常常有须要实现图中需求

最终效果

这样能够,经过修改 v-model 所绑定的值进行二次封装。

3. 结论

分页器的具体逻辑通常都是与交互的设计相关,上述方法将其原理拆分的很清晰,按照具体需求修改一些参数就能够。

往期文章:

原创声明: 该文章为原创文章,转载请注明出处。

相关文章
相关标签/搜索