微信小程序---二次封装 scroll-view 滚动组件

封装的主要目的:
  • 1.对pageNum和pageSize做统一处理
  • 2.控制是否已经在请求中,避免同时触发多次请求
  • 3.控制是否已经请求到最后一条,最后一条之后不再请求

这里解释一下主要需求。虽然微信小程序提供了scroll-view 组件可以很方便到进行滚动加载更多,但是有几个地方在我使用的时候还是需要重复控制。主要是上面三条。 所以我进行一下二次封装

wxml部分

<view class='scroll-container' >
  <scroll-view
        scroll-y
        class='selectionMainScroll'
        style="height:{{srollHeight}}px"
        bindscrolltolower='loadMore'
        scroll-top='{{listScrollTop}}'
  >
      <slot></slot>
  </scroll-view>
</view>

这里要设置滚动区域高度,绑定滚动到底部时执行加载更多,并且控制scroll-top

控制scroll-top的目的时,当我们切换搜索条件进行请求时,要控制将滚动部分滚动到页面顶部

js 部分

import { Fetch } from '../../src/js/fetch.js'
Component({
  properties: {
    srollHeight: {
      type: Number,
      value: 100
    },
    pageNum: {
      type: Number,
      value: 0
    },
    pageSize: {
      type: Number,
      value: 10
    },
  },
  data: {
    listScrollTop: 0,
    canLoad: true,
    notEnd: true,

    params: {},
    url: '',
    loadType: 'insert',
  },
  onLoad: function () {
    this.initDOM()
  },
  methods: {
    /************************************
     * 初始化入口,配置参数
     *
     * params:请求参数
     * url:请求路径
     * loadType: 请求类型
     *
     */
    initScroll(opt) {
      // 如果是插入类型,重置状态
      if (opt.loadType === 'insert') {
        this.setData({
          canLoad: true,
          notEnd: true,
          pageNum: 0,
        })
      }
      // 判断是否为请求中和是否已请求到最后一条
      if (!this.data.canLoad || !this.data.notEnd) {
        return
      }
      let params = opt.params
      params.pageNum = this.data.pageNum
      params.pageSize = this.data.pageSize
      this.setData({
        params: params,
        url: opt.url,
        loadType: opt.loadType,
        canLoad: false
      })
      this.initRequest()
    },
    /************************************
     * 数据请求部分
     */
    // 通过url和参数,初始化请求
    initRequest() {
      wx.showLoading({
        title: '加载中',
      })
      Fetch(this.data.url, this.data.params).then(res => {
        this.triggerEvent('updateListFn', res)
        let notEnd = res.pageSize === res.list.length
        this.setData({
          canLoad: true,
          notEnd: notEnd,
          pageNum: res.pageNum + res.list.length,
          pageSize: res.pageSize,
        })
        if (this.data.loadType === 'insert') {
          this.setData({
            listScrollTop: 0
          })
        }
        wx.hideLoading()
      })
    },
    /************************************
     * 事件触发
     */
    // 向下加载更多
    loadMore() {
      this.triggerEvent('getScrollListFn')
    },
    /**********************************
     * DOM 操作
     */
    // 初始化DOM
    initDOM() {
      this.setData({
        srollHeight: srollHeight,
      })
    },

  }
});
  • 1.初始化时接受传过来的值有:滚动区域高度/开始条数/请求条数长度
  • 2.初始化时将滚动区域高度设置好,这个之后变不再修改
  • 3.请求初始化initScroll,首先判断请求类型,如果是'insert'方式,则进行判断条件当初始化。判断canLoad(是否上一次已加载完毕)和 notEnd(是否已是最后一条),如果不满足则 不再继续请求
  • 4.拿到请求参数和请求路径,并且将pageNum/pageSize添加到请求参数中。
  • 5.请求数据返回后,将返回数据提交给父组件,并更新canLoad/pageNum等条件
  • 6.如果请求类型是insert,则滚动到顶部

父组件部分

    // --------------------------------   wxml部分
<ma-scroll
    srollHeight='{{srollHeight}}'
    bind:updateListFn="updateList"
    bind:getScrollListFn='getScrollList'
    pageNum='{{0}}'
    pageSize='{{10}}'
    id="ma-scroll"
>

    // --------------------------------   js部分

  // 请求滚动列表
getScrollList(type) {
    this.setData({
      showMoreSort: false,
      showFilter: false
    })
    let params = {
      params: this.getlistQuestParams(),
      url: HTTP_URI.GET_PRODUCTS,
      loadType: type || 'insert'
    }
    this.selectComponent('#ma-scroll').initScroll(params)
  },
  // 更新数据列表
  updateList(opt) {
    let arr = []
    if (opt.detail.pageNum === 0) {
      arr = opt.detail.list
    } else {
      arr = this.data.list.concat(opt.detail.list)
    }
    this.setData({
      list: arr
    })
  },

这里首先绑定两个事件给子组件,updateList:更新列表数据;getScrollList:获取列表数据。传入srollHeight/pageNum/pageSize给子组件

初始化时执行子组件初始化方法,并将请求参数和请求类型(insert/concat)传入,这里请求类型loadType是为了区分是否更换搜索条件,因为搜索条件更换时,列表数据需要重置。

更新数据列表:如果pageNum=0,就是返回数据为0条开始,等同于insert方式,直接替换原列表数据。如果不是,则为进一步到请求,需要concat连接数据

随机浏览