【小程序】分页组件封装

参考elementui中分页组件

README.md

参数 说明
total 总条目数
currentPage 当前页数
pageSize 每页显示个数
pagerCount 页码按钮的数量,当总页数超过该值时会折叠
hideOnSinglePage 只有一页时是否隐藏

代码

  1. pagination.ttml
html 复制代码
<view class="pagination">
  <dg-button
    icon="fanyezuo"
    type="text"
    bind:handleClick="handlePrevClick"
    disabled="{{currentPage === 1}}"
    tt-if="{{ pageCount > 0 && !(hideOnSinglePage && pageCount === 1) }}"
  />
  <view
    class="pager"
    bindtap="onPagerClick"
  >
    <view
      tt-if="{{ pageCount > 0 && !(hideOnSinglePage && pageCount === 1) }}"
      class="number {{currentPage === 1 ? 'active' : ''}}"
      data-pager="{{1}}"
    >
      1
    </view>
    <view
      class="number pager-more"
      tt-if="{{showPrevMore}}"
    >
      ...
    </view>
    <view
      tt:for="{{pagers}}"
      tt:for-item="pager"
      class="number {{currentPage === pager ? 'active' : ''}}"
      data-pager="{{pager}}"
    >
      {{ pager }}
    </view>
    <view
      class="number pager-more"
      tt-if="{{showNextMore}}"
    >
      ...
    </view>
    <view
      tt-if="{{ pageCount > 1 }}"
      class="number {{currentPage === pageCount ? 'active' : ''}}"
      data-pager="{{pageCount}}"
    >
      {{ pageCount }}
    </view>
  </view>
  <dg-button
    icon="fanyeyou"
    type="text"
    bind:handleClick="handleNextClick"
    disabled="{{currentPage === pageCount}}"
    tt-if="{{ pageCount > 0 && !(hideOnSinglePage && pageCount === 1) }}"
  />
</view>
  1. pagination.json
javascript 复制代码
{
  "component": true,
  "usingComponents": {
    "dg-button": "/components/button/button"
  }
}
  1. pagination.js
javascript 复制代码
Component({
  options: {
    addGlobalClass: true
  },
  properties: {
    total: {
      type: Number,
      value: 0,
      observer: 'handlePagers'
    },
    currentPage: {
      type: Number,
      value: 1,
      observer: 'handlePagers'
    },
    pageSize: {
      type: Number,
      value: 10
    },
    // 页码按钮的数量,当总页数超过该值时会折叠【大于等于 5 且小于等于 21 的奇数】
    pagerCount: {
      type: Number,
      value: 5
    },
    // 只有一页时是否隐藏
    hideOnSinglePage: {
      type: Boolean,
      value: true
    }
  },
  data: {
    showPrevMore: false,
    pagers: [], // 中间的数字列表
    showNextMore: false,
    pageCount: 0, // 总页数
  },
  methods: {
    handlePagers: function () {
      this.setData({
        pageCount: Math.max(1, Math.ceil(this.properties.total / this.properties.pageSize))
      })

      const pagerCount = this.properties.pagerCount;
      const halfPagerCount = (pagerCount - 1) / 2;

      const currentPage = Number(this.properties.currentPage);
      const pageCount = Number(this.data.pageCount);

      let showPrevMore = false;
      let showNextMore = false;

      if (pageCount > pagerCount) {
        if (currentPage > pagerCount - halfPagerCount) {
          showPrevMore = true;
        }

        if (currentPage < pageCount - halfPagerCount) {
          showNextMore = true;
        }
      }

      const array = [];

      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) {
        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.setData({
        showPrevMore,
        showNextMore,
        pagers: array
      })

    },
    onPagerClick: function (e) {
      const pager = e.target.dataset.pager;
      // 防止用户点击的是...
      if(!pager) {
        return
      }
      this.triggerEvent('currentChange', pager);
    },
    handlePrevClick: function(){
      if(this.properties.currentPage > 1){
        const newVal = this.properties.currentPage - 1;
        this.triggerEvent('currentChange', newVal);
      }
    },
    handleNextClick: function(){
      if(this.properties.currentPage < this.data.pageCount){
        const newVal = this.properties.currentPage + 1;
        this.triggerEvent('currentChange', newVal);
      }
    },
  }
})
  1. pagination.ttss
css 复制代码
.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
}
.pager {
  display: flex;  
  align-items: center;
  justify-content: center;
}
.number {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: rgba(0,0,0,0.65);
  border: 1px solid transparent;
  border-radius: 2px;
}
.active {
  color: var(--color-primary);
  border-color: var(--color-primary);
}
.pager-more {
  color: #CCCCCC;
}

我组件中 没有改变currentPage 是通过emit 然后在外层改变的 如果大家想要在组件中改变的话

那就在那几个函数中新增一个字段 curPage 代表页码。然后currentPage改变的时候赋值给这个值

相关推荐
今日热点20 小时前
小程序主体变更公证线上办理教程|2026 最新材料规范与审核避坑
小程序
Ai-_Man21 小时前
从聊天框到正式文档:AI导出鸭瞄准AI大模型应用的“最后一公里”
开发语言·前端·javascript·人工智能·小程序
省钱兄--zs1 天前
北京24小时自助健身房系统软件开发实战:从架构设计到部署指南
java·数据仓库·spring boot·小程序·需求分析
Ai-_Man1 天前
您您这可以把Grok的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑
光影少年1 天前
Taro 是如何解析入口配置 app.config.ts 和页面配置的?
微信小程序·小程序·typescript·reactjs·百度小程序·taro
DS小龙哥2 天前
从呼吸心率到离床报警:60G雷达睡眠仪全栈开发实录(硬件+MQTT+小程序)DIY一台全功能睡眠监护仪
stm32·单片机·嵌入式硬件·物联网·小程序·智能家居
扶风ff2 天前
练题簿在线免费刷题:刷题、背题、错题复习,一个小程序安排日常备考
学习·小程序
扶风ff2 天前
练题簿在线免费刷题:共享题库、学习任务、在线考试,岗位培训更方便
学习·小程序
愚公搬代码2 天前
【愚公系列】《微信小程序项目实战(AI编程+视频图解)》014-莫凡商城小程序项目视图容器组件的应用
微信小程序·小程序·ai编程
程xu袁2 天前
只有一段副歌,AI写歌选小程序、Suno还是海绵音乐?
小程序·suno·ai音乐·ai音乐工具·ai生成音乐·ai写歌工具