乐趣区

好快-1分钟开发好一个下拉刷新滚动加载列表

好快, 1 分钟写好下拉刷新, 滚动加载自动分页列表

前言

欢迎关注 BUI Webapp 专栏 或者 bui 神速 微信公众号.

以往文章:

  • 2019 开发最快的 Webapp 框架 –BUI 交互框架
  • 微信 Webapp 开发的各种变态路由需求及解决办法!
  • 【BUI 实战篇】BUI 数据驱动做的拼图游戏 Webapp 移动适配版,基于 vuejs 拼图游戏改造
  • webapp 结合 Dcloud 平台打包图文教程
  • 一张脑图看懂 BUI Webapp 移动快速开发框架【上】– 框架与工具、资源

一、观看实操视频

点击观看视频实录

安装完以下环境后, 从 0 到 1, 手把手教, 你也可以做到!

二、开发准备

  • 安装buijs cli 命令行工具(需要先安装 node 环境, 建议使用 node 8.x);

如何安装使用 buijs?

  • 安装bui-fast 快速编辑器插件(推荐vscode);

如何安装使用 bui-fast?

  • 打开跨域的 chrome 浏览器;

如何打开跨域的 Chrome 浏览器?

三、开发过程

使用 buijs 构建工程

  • 1. 创建 Webapp 工程
buijs create demo
  • 2. 安装依赖
cd demo/

npm install

windows 推荐使用淘宝的 cnpm install

  • 3. 运行预览
npm run dev

使用 bui-fast 编辑器插件生成控件

视频里使用的是vscode 可以在安装插件那里找到 bui-fast.

xxx 假设为控件名

生成规则 1:

  • 在 html 里, 使用 ui-xxx 生成控件结构
ui-list

生成以下结构

<div id="uiList" class="bui-scroll">
    <div class="bui-scroll-head"></div>
    <div class="bui-scroll-main">
        <ul class="bui-list">
        </ul>
    </div>
    <div class="bui-scroll-foot"></div>
</div>
  • 在 js 里, 使用 bui-xxx 生成控件的初始化代码
bui-list

生成以下初始化代码

// 列表控件 js 初始化:
var uiList = bui.list({
    id: "#uiList",
    url: "http://rap2api.taobao.org/app/mock/84605/example/getNews",
    pageSize: 5,
    data: {},
    // 如果分页的字段名不一样, 通过 field 重新定义
    field: {
        page: "page",
        size: "pageSize",
        data: "data"
    },
    callback: function(e) {},
    template: function(data) {
        var html = "";
        data.forEach(function(el, index) {

            html += `<li class="bui-btn bui-box">
                <div class="bui-thumbnail"><img src="${el.image}" alt=""></div>
                <div class="span1">
                    <h3 class="item-title">${el.name}</h3>
                    <p class="item-text">${el.address}</p>
                    <p class="item-text">${el.distance}公里 </p>
                </div>
                <span class="price"><i>¥</i>${el.price}</span>
            </li>`
        });

        return html;
    }
});

保存就会自动预览

四、从 bui.list 看自动分页设计原理

常用参数说明:

  • id 用来跟结构绑定
  • url 数据请求的地址
  • data 数据请求需要
  • height 列表的高度
  • page 从第几页开始请求
  • pageSize 要返回多少条数据
  • field 字段映射
  • template 根据返回的数据, 渲染自定义模板, 支持 es6 模板
  • callback 为每一行添加一个点击事件, 比方点击跳转
  • onRefresh 下拉刷新的时候触发回调
  • onLoad 上拉滚动到底部的时候触发回调

1. 滚动自动分页原理

滚动的第一要素就是高度, 当内容撑出容器的高度, 才会产生滚动条, 才能监听 id 的滚动事件, 可以知道是否已经滚动到底部, 到底部则自动发起新一页的请求.

2. 为何有时候会请求多次?

这里我们需要解决的第一个问题, 就是高度, 所以我们可以传 height 参数, 默认是 0, 为 0, 则会自动计算列表的页面剩余高度.

有了高度以后, 我们要计算请求返回的数据能不能撑开容器, 如果不行, 则自动请求下一页, 直到容器被撑开, 所以你会看到pageSize 设置的值较小的时候, 页面会发起第 2 次请求, 就是这个原因.

3. 如何知道返回的数据在哪个字段?

我们来看一下这个接口返回的数据是什么?

http://rap2api.taobao.org/app/mock/84605/example/getNews

这个是淘宝的 mock 模拟接口, 随机返回数据, 返回一个 {data:[],info:"",status:""} 结构的数据.

{
  data: [{
    uid: 6801,
    name: "和再团之较",
    image: "http://dummyimage.com/200x134/4A7BF7&text=Thumbnail",
    phone: "17612327699",
    location: "惠城区",
    price: "65",
    distance: "52",
    status: 1,
    date: "2003-06-28",
    url: "gopher://brcce.cq/svku",
    email: "v.dmdtjgv@rwldcexzt.bi",
    time: "20:39:53",
    address: "海南省 三沙市 西沙群岛",
    detail: "式始众组月他政例了部自革每往子。但本活又己交给音长争标识我。八说前它特用达圆是路看江才。开次他争从点军容给油很出。成育料技所心并精北酸间办元。除现七团一历积动两水矿花始线党党她。"
  }],
  info: "获取成功",
  status: 0
}

那么问题来了? 不管接口的规则是后端还是前端定的, 控件并不事先知道接口的规则, 如果把规则限定死了, 那很多先开发接口再来学习移动端开发的还会选择 bui 框架吗?

我们来看看有没有漏了什么参数?

  • field 字段配置

这个就是用来做数据请求的字段映射, 比方, 我请求的接口地址是http://rap2api.taobao.org/app/mock/84605/example/getNews, 请求第几页是用的大写 PAGES 请求每页的大小 是用的 PAGESIZES; 那么 field 的配置应该为:

{
  page: 2,
  pageSize: 20,
  field: {
    page: "PAGES",
    size: "PAGESIZES"
  }
}

那么接口就会请求为 http://rap2api.taobao.org/app/mock/84605/example/getNews?PAGES=2&PAGESIZES=20; 这样接口就能正常请求到对应的数据了, 那请求到以后的数据返回回来, 怎么知道数据在什么字段呢? 同样也是在 fielddata 参数里面配置;

{
  page: 2,
  pageSize: 20,
  field: {
    page: "PAGES",
    size: "PAGESIZES",
    data: "data"
  }
}

如果返回的数据是嵌套多个层级呢? 比如返回

{
  result: {
      data: [{
        uid: 6801,
        name: "和再团之较",
        image: "http://dummyimage.com/200x134/4A7BF7&text=Thumbnail",
        phone: "17612327699",
        location: "惠城区",
        price: "65",
        distance: "52",
        status: 1,
        date: "2003-06-28",
        url: "gopher://brcce.cq/svku",
        email: "v.dmdtjgv@rwldcexzt.bi",
        time: "20:39:53",
        address: "海南省 三沙市 西沙群岛",
        detail: "式始众组月他政例了部自革每往子。但本活又己交给音长争标识我。八说前它特用达圆是路看江才。开次他争从点军容给油很出。成育料技所心并精北酸间办元。除现七团一历积动两水矿花始线党党她。"
    }],
  },
  info: "获取成功",
  status: 0
}

那么我们就要找到该数据返回的数组字段在哪里? 你可以这样配置.

{
  page: 2,
  pageSize: 20,
  field: {
    page: "PAGES",
    size: "PAGESIZES",
    data: "result.data"
  }
}

4. 如何知道已经到最后一页了?

我们操作一下刚刚生成的控件, 会看到底部有 没有更多内容 字样, 那怎么知道是否是最后一页了呢? 通过 返回的数组大小 , 跟你请求的 每页大小 做比对, 如果小余 pageSize 设置的值, 则认为已经是最后一页了.

实际上就是把 bui.ajax+bui.scroll+bui.pullrefresh几个控件的通用需求整合在一块, 这样我们就可以解决数据接口 + 控件整合, 又能抽离业务的一个控件. 通过简单配置, 我们可以满足很多开发需求.

五、注意事项

  • 对于接口的请求必须返回数组才能操作, 非数组请使用 bui.scroll 控件;
  • 如果高度自动计算不准确, 需要自行计算好告诉它;
  • 如果是 restful 接口, 需
退出移动版