评论

利用Behavior实现列表分页数据自动加载封装

你是否有在每个分页加载数据的页面都要写一遍分页加载的逻辑,在每个onload、onReachBottom、onPullDownRefresh都要做相同的处理而引起代码冗余的烦恼呢?这篇文章能帮到你!

onload-more.js的内容如下

/*
* 分页加载数据
*/
const onloadMore = Behavior({
   // 组件加载
   attached() {

      if (thisdata.autoOnload) { // 开启自动加载数据let pages = getCurrentPages()let page = pages[pages.length - ]

         this.onShow()
         if (thisdata.onShowRefresh) { // 每次onShow都刷新数据// 拦截当前页面的onShow事件let oldOnShow = page.onShow
            page.onShow = () => {
               if (this.isActive()) {
                  this.onShow()
               }

              if (oldOnShow) {
                  oldOnShow()
               }
            }
         }

         // 拦截当前页面的上拉触底事件let oldOnReachBottom = page.onReachBottom
         page.onReachBottom = () => {

           if (this.isActive()) {
               this.onReachBottom()
            }

           if (oldOnReachBottom) {
               oldOnReachBottom()
            }
         }

        if (thisdata.isPullDownRefresh) {
            // 拦截当前页面的下拉刷新事件//需要设置 "enablePullDownRefresh": true,let oldOnPullDownRefresh = page.onPullDownRefresh
            page.onPullDownRefresh = () => {

              if (this.isActive()) {
                  this.onPullDownRefresh()
               }

              if (oldOnPullDownRefresh) {
                  oldOnPullDownRefresh()
               }
            }
         }

     }
   },
   // 组件移除
   detached() {
      // 组件移除后不再加载数据this.setData({
         isInit: false
      })
   },
   observers: {
      'params': function () { // 参数变化时初始化列表this.initList()
      }
   },
   data: {
      autoOnload: true, // 是否自动加载数据,自动加载数据通过拦截页面的事件和生命周期实现
      onShowRefresh: true, // 是否每次进入页面都刷新数据,当autoOnload为true时可用
      isPullDownRefresh: true, // 是否开启下拉刷新
      api: '', // 请求接口地址
      isLoading: false, // 是否加载中
      isEnd: false, // 数据是否已加载完毕
      list: [], // 加载到的数据列表
      page: {
         pageNum: , // 当前第几页
         pageSize: 10// 每页多少条
      },
      params: {}, // 请求额外参数
      isInit: false// 列表数据是否已经初始化
   },
   methods: {
      isActive () {
         returnthis.data.isInit
      },
      // 组件所在页面的onShow事件
      onShow () {
         this.initList()
      },
      // 组件所在页面的onReachBottom事件
      onReachBottom () {
         // 加载更多if (!thisdata.isEnd && !thisdata.isLoading) {console.log('触底加载')this.loadData()
         }
      },
      // 组件所在页面的onPullDownRefresh事件
      onPullDownRefresh () {
         // 初始化数据this.initList()
         setTimeout(() => {
            wx.stopPullDownRefresh()
         }, 400)
      },

     // 初始化列表
      initList: function () {
         this.setData({
            page: {pageNum: , pageSize: 10},
            isEnd: false
         }, () => {
            this.loadData(true)
         })
      },
      // 加载数据成功
      loadDataSuccess (isInit) {
         if (isInit) {
            // 列表数据初始化完成
         } else {
            // 当前页数据加载完成
         }
      },
      // 加载数据
      loadData: function (isInit) {

        if (thisdata.isEnd || !thisdata.api) {
            return
         }

        this.setData({
            isLoading: true
         })
         wx.$request({  // wx.$request是我在wx.request的基础上做了简单的封装
            url: thisdata.api,
            data: Object.assign({}, thisdata.page, thisdata.params)
         }).then(res => {
              // res的格式
              /* let res = {
                   code: 200,
                  data: {
                  rows: []
                 }
            } */
          this.loadDataSuccess(isInit) // 加载数据成功

           let list = thisdata.list
            let obj = {
               isEnd: res.data.rows.length < thisdata.page.pageSize, // 判断是否结束
               isLoading: false,
               page: Object.assign({}, thisdata.page, {pageNum: thisdata.page.pageNum + }) // pageNum + 1
            }
            if (!isInit) { // 加载第二页及以上数据// 数据局部更新
               res.data.rows.forEach(item, i) => {
                  obj['list['+ (list.length + i) + ']'] = this.filterItem(item, list.length + i)
               })
            } else { // 初始化列表

              obj.isInit = true
               obj.list = res.data.rows.map(item, i) =>this.filterItem(item, i))
            }

           this.setData(obj)

        }).catch(() => {
            this.setData({
               isLoading: false
            })
         })
      },
      // 过滤item,oldIndex为在list中的index
      filterItem (item, oldIndex) {
         return item
      }
   }
})
module.exports = {onloadMore}

使用方法

注意:Behavior只能在组件中使用

information组件中使用


loading组件主要是数据加载中、数据为空、数据加载完成的提示

效果

information组件就是列表部分

最后

代码片段:https://developers.weixin.qq.com/s/vazUgPmi7kdQ

第一次写如果有人看我就更新多一些用法,还有如果大家有更好的建议欢迎一起交流啊

最后一次编辑于  2019-12-24  
点赞 4
收藏
评论

3 个评论

  • 神经蛙
    神经蛙
    2020-05-16

    你好

    请问一下,我的组件A引用了Beahvior的数据,然后我在另一个组件B中触发了behavior中的方法,改变了data,但是组件A中的模版数据不发生变化,请问有遇到过类似的问题?是怎么解决的呢?

    2020-05-16
    赞同
    回复
  • Samuel
    Samuel
    2020-04-07
    哥们,你遇到过ios系统的微信7.0.4版本用Behavior的问题吗?我这边测试这个版本微信用不了,知道这个自定义组件的Behavior是最低支持什么版本微信吗
    


    2020-04-07
    赞同
    回复 1
    • 真有毅丝
      真有毅丝
      2020-09-23
      现在好使了么
      2020-09-23
      回复
  • TNT
    TNT
    2019-12-23

    那多写点,先点赞,当然 最后如果能有个代码片段是挺好的~https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html

    2019-12-23
    赞同
    回复 2
登录 后发表内容