微信小程序懒加载的实现

近期做了一个微信小程序的项目, 其中涉及到微信小程序的懒加载功能, 第一次做这个功能的感觉真的是让人欲(tou)罢(teng)不(bu)能(yi)啊, 所以在这里做一个小小的总结来分享一下.

不同于原始的dom操作项目, 现在的现代框架已经将dom操作高度集成到了api中, 采用数据驱动的方式, 来实现对dom的各种处理.

现在我们回忆一下当初那个青涩的原始时代, 当有懒加载的需求的时候, 我们可以开心地创建一个ajax请求, 将请求参数发送到后台, 后台反馈给我们参数后, 然后我们再开心地操作dom将数据处理后插到页面上.

“哎呀, 屁股好疼” —页面上的某个dom节点如是说

但是在数据驱动, 高度组件化处理ajax的返回参数的时候, 我们该怎么处理这个需求呢?

微信小程序的scroll-view组件

说到懒加载, 那么就必须得提到微信的scroll-view组件, 这玩意儿干啥的呢?

主要的作用还是作为一个载体, 用于设置载体内的内容滚动, 当然, 如果需要在y轴滚动的话, 页面都是有这个功能的, 但是如果直接使用y轴滚动的功能的话, 就无法成功触发相应的事件了.

wxml的写入方式

我们将wxml中需要滚动的view外需要再套一层scroll-view方便让器其滚动触发事件

有一点需要特别特别注意的是, 微信原生提供了bindscrolltolower和bindscrolltoupper这两个api来专门处理对应的滚动触底(最右边或最下边)及滚动触顶(最左边或最上边)事件.

但是!!!

这两个事件的触发, 前提是必须要在对应的scroll-view上设置高度才可以的, 不然事件无法触发生效.

比如说, 针对不同的设备, 我设置了对应的触发高度

1
2
3
4
5
6
7
8
9
10
@media (min-width: 375px) {
.all-movie{
height: 1300rpx;
}
}
@media (max-width: 374px) {
.all-movie{
height: 1000rpx;
}
}

ajax的请求分析

在这里要特别说明一下, 因为微信不存在dom操作, 所以我们进行懒加载操作的时候, 其实是将整个页面的所有元素都重新加载了一遍的, 因为插不进去啊(#→⌒→).

那么这个时候ajax的请求就很成问题了, 我们每次加载, 需要传递不同的参数进去

那么我的思路就是, 通过在data上挂载变量, 每次请求将变量增加, 然后通过这个变量的值的增加, 每次发起的ajax请求就不一样了, 获取到的值会逐次增加

微信小程序的ajax创建方式这里就不再赘述了, 官网说的很清楚, 使用wx.request对象很容易搞定

下面是我写在ajax请求success里面的代码

1
2
3
4
5
6
7
8
// 获取请求到的数据
var data = res.data
// 将本身setdata的对象直接拿出来, 然后再放进去
var dataCon = {}
// 每产生一次ajax请求, 就要使总和加10, 也就是再请求十条数据
that.data.totalCount += 10
dataCon.dataObj = data
that.setData(dataCon)

注意上面我是设置了一个data的数据名为totalCount, 初始值我设置其为0, 那么每次产生一次ajax 请求, 则其自加10, 通过totalCount, 在拼接上对应的请求url, 就可以成功取到相应的ajax返回值了.

到这里可能会有同学要问了, 你这里每次都要重新渲染一下页面, 难道不会增大微信小程序的压力吗? 每次请求的数据都会增加, 页面压力会很大啊

当然, 既然使用数据驱动的方式来进行开发, 对于这样的场景, 产生较大的数据压力是必然的, 但是微信小程序和浏览器一样, 本身是存在缓存的, 之前请求过的数据, 后面服务器会直接返回403, 就不会产生较大的数据流, 最后产生流量的也就是后面那一小部分的文件数据而已.

对ajax请求的优化

以上方法可行肯定是可行的, 但是我们每次做ajax请求, 每次的请求数据都会增多, 那么会不会有一种更加的请求方案呢?

当然, 我们可以考虑和之前操作dom那样, 每次只请求自己需要的那一部分数据, 之前重复的数据是没有必要再到服务器请求一次的

我们的url可以这样构建

1
var nextUrl = this.data.requestUrl + "?start=" + this.data.totalCount + "&count=10"

totalCount表示已经请求的数量, 而count表示每次请求的数量

很好, 一下减少了不少的ajax请求压力

优化后的bug处理

ajax请求的压力确实减少了, 但是现在还有一个问题啊, 你每次都反馈给我十条数据, 我用你给的数据渲染, 岂不是把页面懒加载变成了页面刷新了, 每次请求的数据是不一样了, 但是之前的数据已经不存在了呀

所以, 我们需要使用一个data上面的变量来存储我们之前请求到的值

我们将之前的成功回调改写一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 获取请求到的数据
var data = res.data
// 将本身setdata的对象直接拿出来, 然后再放进去
var dataCon = {}
// 每产生一次ajax请求, 就要使总和加10, 也就是再请求十条数据
that.data.totalCount += 10
var total = {}
// 如果不是第一次请求数据的话,则将两次的数据相加
if (!that.data.isEmpty) {
total = that.data.dataObj.concat(data)
} else {
total = data
// 如果isEmpty为true则将其改为false
that.data.isEmpty = false
}
dataCon.dataObj = total
that.setData(dataCon)

这里我们设置了一个全局变量isEmpty, 默认为true, 表示默认为空, 当第一次请求的时候, 将数值存入total中,并将isEmpty改写为false, 之后的每一次请求都是在total中加数据, 我们渲染的话就都是用全局的dataObj这个变量来进行渲染, 即可解决之前的问题.

更新:
后面有看到因为scroll-view在页面中是无法触发下拉刷新事件的,但后面微信方给出了解决办法: 不用scroll-view , 玛德坑爹

现在可以直接使用onReachBottom事件,也就是触底事件来处理和进行懒加载, 相比于之前的方法简单了不少, 页面也更加流畅了

期待小程序能带了更多更好的东西吧
文章目录
  1. 1. 微信小程序的scroll-view组件
  2. 2. wxml的写入方式
  3. 3. ajax的请求分析
  4. 4. 对ajax请求的优化
  5. 5. 优化后的bug处理
|