微信小程序实现分页查询,封装分页对象。

分页逻辑如果需要在多个页面使用,每次都写重复的代码显然很繁琐,所以将其封装为一个对象,因为对象可以保存状态,所以当初始化 了一个对象之后每次只需调用该对象的一个getMoreData方法即可查询数据,不用多写任何逻辑,基于这个思想实现了分页对象。

一、问题引出:

当实现上述方法时,要解决以下问题:

1、构造方法:

  • req对象(url、method、data)
  • start和count参数

2、请求上锁:

为了防止服务器请求数据慢,所以给服务器上锁,环节服务器压力,只有当当前请求结束之后才能进行下一次的请求。

3、url的拼接:

请求的是get的拼接参数,所以当url中有?时需将&拼接上,当无?时将?start=拼接上。

4、数据的返回:

  • 返回null,此时说明服务器出现异常、故障或请求正在上锁,调用方同时直接return即可。
  • 统一数据格式,下文代码处有体现,返回四个参数。

二、paging对象代码:

import {
    Http
} from "./http";

class Paging {
    /*提供getMoreData的接口,外界只需要调用这个方法就可以无限次的获取更多数据
     * 1、提供构造方法,将req对象传入,包括get/post方法、data、url等信息。
     * 2、书写外部使用的getMoreData方法
     *   1.需要加锁和解锁的过程,防止用户重复发请求,只有当该条数据返回之后才能进行
     *   2.只有当还有更多数据时才会发送请求
     * 3、获取真实数据:
     *   1.确定好url,即将url拼接好,因为参数是?填上去的,但是如果前面已经有?则要使用&链接
     *   2.发送http请求,获取数据
     *   3.判断 1错误 2数据为空  返回的结果不同,错误会进入全局异常管理,空就返回对应数据结构的空值。
     *   4。计算是否还有更多数据,有的话就让start+=count
     *   5.将上面得到的数据与原数据拼接。
     *   6.返回对应的数据
     * */

    req
    count
    start
    moreDataFlag = true // 是否还有更多数据
    locker = false
    url = ''
    accumulator = []


    //构造方法
    constructor(req, count = 10, start = 0) {
        this.req = req
        this.count = count
        this.start = start
        this.url = this.req.url
    }

    //获取更多数据:
    async getMoreData() {
        //上一次请求还没结束
        if (this._isLock()) {
            return null
        }
        //没有更多数据了
        if (!this.moreDataFlag) {
            return null
        }
        const data = await this._getActualData()
        //请求结束,释放锁
        this._releaseLock()
        return data
    }

    async _getActualData() {
        //1、确定好url
        const req = this._deaReqlUrl()
        //2、发送请求
        const paging = await Http.request(req)
        if (!paging) {
            //服务器端出现了异常
            return null
        }
        //服务器没有数据了
        if (paging.total === 0) {
            return {
                empty: true,
                items: [],
                moreData: false,
                accumulator: []
            }
        }
        //计算是否还有更多数据
        this.moreDataFlag = this._accumulateMoreDataFlag(paging.total_page, paging.page)
        //存在更多数据就要更新索引
        if (this.moreDataFlag) {
            this.start += this.count
        }
        //得到返回的数据
        this._getAccumulator(paging.items)
        return {
            empty: false, //是否为空
            items: paging.items, //当前请求得到的数据
            moreData: this.moreDataFlag, // 是否还有更多数据
            accumulator: this.accumulator //之前数据+刚刚得到的数据
        }
    }

    //将新老数据拼接在一起
    _getAccumulator(items) {
        //concat函数必须要接收,不是引用类型的追加
        this.accumulator = this.accumulator.concat(items)
    }

    //计算是否还有更多数据
    _accumulateMoreDataFlag(total_page, page) {
        return page < total_page - 1 //页码从0开始
    }


    //处理url问题
    /**
     * 因为接收到的req内url需要将start和count拼接上去,所以这步就是处理url问题
     * */
    _deaReqlUrl() {
        let url = this.url
        const param = `start=${this.start}&count=${this.count}`
        //传来的req中的url类似与'/v1/spu?id=2'或'/v1/spu'
        if (url.includes('?')) {
            url += '&' + param
        } else {
            url += "?" + param
        }
        this.req.url = url
        return this.req
    }

    //加锁 默认是false
    _isLock() {
        if (!this.locker) {
            this.locker = true
            return false
        }
        return true //上锁了
    }

    //释放锁
    _releaseLock() {
        this.locker = false
    }
}

export {
    Paging
}

上面引用的http类:

import {config} from "../config/config";
import {promisic} from "./util";
//传来的url格式类似 latst/spu
class Http {
    static async request({url, data, method = 'GET'}) {
        const res = await promisic(wx.request)({
            url: `http:localhost:8080/v1/${url}`,
            method,
            data,
        })
        return res.data
    }
}

export {
    Http
}

调用方代码:

    async initBottom() {
       //创建分页对象
        const paging = new Paging({
            url: "spu/latest",
            method: 'GET'
        }, 5, 0)
        //分页加载更多也需要,所以将对象保存起来
        this.paging = paging
        //获取数据
        const data = await paging.getMoreData();
        //出现异常或上锁时等情况
        if (!data) {
            return
        }
    },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值