自学小程序之路(五),列表加载数据,下拉刷新和上拉加载

加载数据: 

说到列表,在Android 中大部分都是和数组或者list容器绑定。

小程序中也是这么个思想。但是可能数据表现形式有所不同。

所以先了解一下js中表示数据集合的数组。

js中的数组的表示方式是[ a, b, c],组内元素用 ,隔开。

声明方式

1.var cars = ["Saab", "Volvo", "BMW"];

2.var cars = new Array("Saab", "Volvo", "BMW");

一般都是用第一种。

用cars[0] 来表示第一个,和Java的语法一样。

//Arraytest.js
Page({
  data: {
    numberArray: [1, 2, 3, 4]
  }
})

在js文件的data中定义了数组。

在wxml中

//ArrayTest.wxml
<!—- 遍历数组,并为数组中的每一个值创建一个switch开关 —->
<switch wx:for="{{numberArray}}" 
style="display: block;"> {{item}} </switch>

组件用到了wx:for属性,也就是说这个组件绑定了一个数组,就是说数组中有几个元素,就会把这个组件渲染几个。内容item则指的是每个元素。

也就是说不出意外的话,上面的代码应该会显示4个开关。

  那么如果item是对象的话,我们可以针对每个元素对象的某个属性{{item.attr}}进行展示。

<!--arraytest/arraytest.wxml-->
<switch style="display:block"
wx:for="{{numberArray}}">{{item}}</switch>
<view style="width:100%;height:1px;background-color:#999999;margin-top:30rpx;margin-bottom:30rpx"></view>
<!-- 展示对象数组中的name属性 -->
<button style="display:block"
wx:for="{{objectArray}}" wx:key="id">{{item.name}}</button>
// arraytest/arraytest.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    objectArray:[
      {
        id: 1,
        name: "第一选择"
      },
      {
        id: 2,
        name: "第二选择"
      },
      {
        id: 3,
        name: "第三选择"
      },
      {
        id: 4,
        name: "第四选择"
      },
    ],
      numberArray:[1,2,3,4]
  }
}

当我们修改了数组中某一项的数据时,布局中的列表会全部刷新吗?

不会,如果你设置了wx:key的话会把组件和这个数据通过key绑定。

 设置key后,改变数组中的某一项之后,布局中会找到这一项的key然后去刷新列表中对应key的组件。

wx:key 的值以两种形式提供

  • 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
  • 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。

如果组件绑定了数组,记得设置key,如果不设置key的话会收到警告

下拉刷新

知道了列表的绑定数据,再来看下Android中列表经常用到的下拉顺新和加载更多。

如果这样的话,需要给列表包括一个组件scroll-view 

https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html

 撸起袖子上代码

注释很重要,重要!!!

<!--scrollview/scrolltest.wxml-->
<view class="container">
  <text style="flex:0">scrollview/scrolltest.wxml</text>

<!-- 
  1.refresher-enabled 是否开启下拉刷新
  2.refresher-default-style定义下拉刷新的loading小点点的颜色;
 3.refresher-background 下拉区域的背景色。官网说默认白色,试验如果不设置的话是透明
 4.refresher-triggered 设置当前的刷新状态。用于自动刷新或者关闭刷新时
 5.bindrefresherrefresh 下拉刷新时触发的方法 2.10以后才可以用
 6.bindrefresherrestore 下拉刷新被复位是,即下拉刷新完成的的触发方法
 7.bindscrolltolower 滚动到底部的方法,可以用来监测上拉加载-->
<scroll-view class="scrollview-style" scroll-y="true"
bindscrolltoupper="onRefresh"
bindscrolltolower="onLoadMore"
refresher-enabled="{{true}}"
refresher-background="#FFFFFF"
refresher-triggered="{{refreshing}}"
bindrefresherrefresh="onRefresh"
bindscrolltolower="onLoadMore"
>
<text wx:for="{{attr}}" style="display:block;height:200rpx" wx:key="*this">{{item}}</text>
</scroll-view>
<!--<button type="primary">bottom</button>-->

</view>

样式文件

/* scrollview/scrolltest.wxss */
page{
  height: 100%;
}
.container{
  display: flex;
  flex-direction: column;
  height: 100%;
}
.scrollview-style{
  width: 100%;
  flex: 1;
  background-color: red;
}

js文件

// scrollview/scrolltest.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    attr: ["item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8", "item9", "item10"],
    refreshing: false,
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
    /**
   * 下拉刷新
   */
  onRefresh: function (e) {
    setTimeout(() => {
      // 设置3秒后停止刷新
      this.setData({
        refreshing: false,
      })
    }, 3000);
  },
})

主要是最后那个方法。来控制下拉刷新,并控制3秒后,停止刷新。

最后的效果

上拉加载

先说坑:

当我兴冲冲的用scroll-view中的bindtoscrolllower属性来绑定了js中的方法后,却发现这条路根本行不通。每次scrollview滑动到底部并没有触发这个方法。

看了看官网是这样说明的

 但是我们用的是flex来确定的他的高度,实际上scrollview会根据内容来自己计算出高度,而flex中的flexbasis属性默认为auto,在scrollview的height面前是不起作用的。所以scrollview的高度会认为是我们的10个item的总高度。当我们向上滑动时,其实是向上滑动的整个页面内容,而不是scrollview中的内容进行滚动,自然不会触发bindtoscrolllower方法。可以看下动画。会发现页面的其余组件也随着向上滚动而向上移出了页面。

可以看到页面上方的文本也被移出了页面。 也就是说我们滚动的是整个页面,而不是scrollview中的内容。

那么如何让scrollview的高度确定在 下方的区域,然后让其内容跟随滚动呢。

我查了大佬的做法。最后选择了这个文章中的方法。

https://blog.csdn.net/Abudula__/article/details/86667922

 应用到我这个粗陋的demo中,解决思路就是这样的:

  1. 在scrollview外面套一层view让这个view的flex是1,即填满页面除去顶部的text的剩余空间。
  2. 将scrollview的position设置为absolute,并且填满view。
  3. view的position设置为relative,这个设置很重要。否则scrollview的absloute就会一直寻找position不是static的父组件填满。

解决办法: 

看下最后的代码

<!--scrollview/scrolltest.wxml-->
<view class="container">
  <text style="flex:0">scrollview/scrolltest.wxml</text>
  <!-- position一定要设置 -->
<view style="flex:1;background-color:purple;position:relative">
<!-- 
  1.refresher-enabled 是否开启下拉刷新
  2.refresher-default-style定义下拉刷新的loading小点点的颜色;
 3.refresher-background 下拉区域的背景色。官网说默认白色,试验如果不设置的话是透明
 4.refresher-triggered 设置当前的刷新状态。用于自动刷新或者关闭刷新时
 5.bindrefresherrefresh 下拉刷新时触发的方法 2.10以后才可以用
 6.bindrefresherrestore 下拉刷新被复位是,即下拉刷新完成的的触发方法
 7.bindscrolltolower 滚动到底部的方法,可以用来监测上拉加载-->
 <scroll-view class="scrollview-style"  
scroll-y="true"
refresher-enabled="{{true}}"
lower-threshold="{{10}}"
refresher-background="#FFFFFF"
refresher-triggered="{{refreshing}}"
bindrefresherrefresh="onRefresh"
bindscrolltolower="onLoadMore"
>
<text wx:for="{{attr}}" style="display:block;height:200rpx" wx:key="*this">{{item}}</text>
</scroll-view> 
</view>
<!-- <button type="primary" style="flex:0 1 auto">bottom</button> -->

</view>
/* scrollview/scrolltest.wxss */
page {
  height: 100%;
}

.container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.scrollview-style {
  background-color: red;
  /* 填满父控件 */
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

js文件,只贴上了加载更多方法,其余地方和之前的js文件代码 一样。

加载更多的意思是在列表对应的数组每次多4个item,并更新到列表上。

  /**
   * 加载更多
   */
  onLoadMore: function (e) {
    console.log("onLoadMore");
    let length = this.data.attr.length;
    this.data.attr = this.data.attr.concat(["item" + (length + 1), "item" + (length + 2), "item" + (length + 3), "item" + (length + 4)]);
    console.log(this.data.attr);
    this.setData({
      attr: this.data.attr,
    })
  }

这样,就完成了将scrollview的大小确定在剩余的空间内。

看下效果:

 好了。至此,页面的加载数据,刷新和加载更多就写的差不多了。

如果对position不熟悉的地方,可以参考css教程中的关于【定位】的章节。

https://www.w3school.com.cn/css/css_positioning.asp

 拜了拜。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值