• 全栈之路-杂篇-前端分页封装优化


      分页在项目中是很普遍存在的,如何封装才能让使用者使用方便,让代码可读性强,之前在写代码的过程中,很少注意这方面的东西,但是随着年龄的增大,作为程序员,面子肯定是要的,就像我想写的一手好字,同样,我也想写出优雅的代码!七月老师的风袖项目,这里的场景是小程序中的分页实现,里面那个分页的封装很值得学习,简单记录一下!

    一、微信小程序中分页问题

    微信小程序中分页需要考虑哪些方面呢?如何才能做好一个分页呢?以下这些方面存在的问题,你在做小程序中分页的时候考虑到了吗?反正我在做分页的时候是没有考虑这么全面的,没事,一直在学习的路上!

    1、一条数据也没有,为空的情况

    2、是否是最后一页,还有没有更多数据

    3、请求分页数据的累加

    这个不像PC端分页,有严格的分页按钮来点击,你点击哪页的数据,我来请求加载哪页的数据就行,小程序中的分页是用户触发上拉触底事件,来进行更多也就是下一页数据的加载的,这里就存在分页数据累加的问题,需要将已经请求的数据和请求的下一页数据进行累加,然后使用setData()方法进行重新渲染,显示出来,例如:总共有100条数据,第一次加载1-20,第二次加载21-40 显示1-40数据 ... 直到100数据加载完成,提示用户加载完成,没有更多数据

    4、分页数据的加载状态

      非分页数据  a 正在加载  b 空

      分页数据      a 正在加载  b 加载完成  c 空

    5、上滑触低,加载分页数据,避免用户重复发送过多请求,导致数据库查询次数过多,数据库崩溃

    二、代码实现

    将分页相关的方法封装成Paging类,调用使用方直接实例化Paging类。然后调用getMoreData()方法进行分页数据的请求

    1、paging类整体结构搭建(毛坯房)

    (1)封装类的时候首先明确需求,这里的具体就是想要获取到分页数据,那么Paging类中需要一个方法来实现这个需求

    (2)getMoreData()方法 相当于Generator 生成器中的next方法

    (3)参数如何处理 如何传递到Paging类中 这里用到的是constructor 构造器 初始化一些必要的参数

     1 class Paging{
     2   start
     3   count
     4   url
     5 
     6   constructor(url, count, start){
     7     this.count = count
     8     this.start = start
     9     this.url = url
    10   }
    11   getMoreData(){
    12     //生成器 generator
    13   }
    14 }

    2、Paging类主方法简单封装(改水,改电,铺地板)

    (1)看看最重要的getMoreData()方法,如何进行数据的获取 这里首先需要考虑的就是数据锁的问题,封装_getLocker()和_releaseLocker()方法

    (2)尝试着将数据锁加到getMoreData方法中

    (3)新建一个真正的获取数据的方法 _actualGetData()方法

     1 class Paging{
     2   start
     3   count
     4   url
     5   locker = false //创建locker属性
     6 
     7   constructor(url, count, start){
     8     this.count = count
     9     this.start = start
    10     this.url = url
    11   }
    12   getMoreData(){
    13     //生成器 generator
    14     if(!this._getLocker()){
    15       return
    16     }
    17     this._actualGetData()
    18     this._releaseLocker()
    19   }
    20 
    21   _actualGetData(){
    22     // 真实获取数据的方法 需要调用Http的request方法 传递一个Object参数对象
    23   }
    24 
    25   _getLocker(){
    26     // 获取锁
    27     if(this.locker){
    28       return false
    29     }
    30     this.locker = true
    31     return true
    32   }
    33   _releaseLocker(){
    34     this.locker = false
    35   }
    36 }

    3、获取真实数据的方法封装(刷白,吊天花板,吊灯)

    (1)首先需要考虑的是 调用方需要传递请求参数、url、请求方式,需要封装成一个Object对象 这里就是req,将原来的url参数换成req

    (2)url 例:v1/spu/latest?start=0&count=10 后面的参数需要进一步的封装,才能使用方便 使用方只需要传递 url:v1/spu/latest 这种就行

    (3)getCurrentReq() 方法中,当频繁的进行调用的时候,我们从this.req中取出url,可能导致url重复拼装,最终得到错误的url 解决方法是重新提取出url参数

    (4)对返回结果的封装,返回特定的一个数据结构

    (5)对于moreData的判断 写在函数中,因为很多地方需要使用,这里的处理方式是将moreData封装成一个属性

    (6)处理累加器的accumulator 封装为一个属性 写一个累加的方法进行累加操作

    (7)调用请求之前进行moreData的判断

      1 import {
      2   Http
      3 } from "./http";
      4 class Paging {
      5   start
      6   count
      7   req
      8   locker = false //创建locker属性
      9   url // 添加url属性,解决url重复叠加问题
     10   moreData = true
     11 
     12   constructor(req, count, start) {
     13     this.count = count
     14     this.start = start
     15     this.req = req
     16     this.url = req.url
     17   }
     18   async getMoreData() {
     19     if(!this.moreData){
     20       return
     21     }
     22     //生成器 generator
     23     if (!this._getLocker()) {
     24       return
     25     }
     26     const data = await this._actualGetData()
     27     this._releaseLocker()
     28     return data
     29   }
     30 
     31   async _actualGetData() {
     32     // 真实获取数据的方法 需要调用Http的request方法 传递一个Object参数对象
     33     const req = this._getCurrentReq()
     34     let paging = await Http.request(this.req)
     35     if (!paging) {
     36       return null
     37     }
     38     if (paging.total === 0) {
     39       // 不存在分页数据
     40       return {
     41         empty: true,
     42         items: [],
     43         moreData: false,
     44         accumulator: []
     45       }
     46     }
     47     // 对moreData进行判断 因为这个变量需要很多地方用 把这个属性封装成属性
     48     this.moreData = this._moreData(paging.total_page, paging.page)
     49     if (this.moreData) {
     50       this.start += this.count
     51     }
     52     // 累加操作
     53     this._accumulate(paging.items)
     54     return {
     55       empty:false,
     56       items:paging.items,
     57       moreData:this.moreData,
     58       accumulator:this.accumulator
     59     }
     60   }
     61 
     62   _accumulate(){
     63     // 分页数据累加的方法
     64     this.accumulator = this.accumulator.concat(items)
     65   }
     66 
     67   _moreData(totalPage, pageNum) {
     68     // 总页数 当前页码
     69     return pageNum < totalPage - 1
     70   }
     71 
     72   _getCurrentReq() {
     73     // 封装req参数
     74     let url = this.url
     75     const params = `start=${this.start}&count=${this.count}`
     76     if (url.includes('?')) {
     77       url += '&' + params
     78     } else {
     79       url += '?' + params
     80     }
     81     thi.req.url = url
     82     return this.req
     83   }
     84 }
     85 
     86 _getLocker() {
     87   // 获取锁
     88   if (this.locker) {
     89     return false
     90   }
     91   this.locker = true
     92   return true
     93 }
     94 _releaseLocker() {
     95   this.locker = false
     96 }
     97 }
     98 
     99 export {
    100   Paging
    101 }

    4、封装完成

    其他操作请自行完成!!!

     内容出处:七月老师《从Java后端到全栈》视频课程

    七月老师课程链接:https://class.imooc.com/sale/javafullstack

  • 相关阅读:
    Beta冲刺——集合随笔
    Beta冲刺——用户调查报告
    Beta冲刺——总结
    Beta冲刺——代码规范、冲刺任务与计划
    Beta冲刺——Day 7
    Beta冲刺——Day 6
    Beta冲刺——Day 5
    Beta冲刺——Day 4
    Beta冲刺——Day3
    beta冲刺汇总
  • 原文地址:https://www.cnblogs.com/ssh-html/p/11834587.html
Copyright © 2020-2023  润新知