支付宝小程序 UI·上滑加载更多
小程序列表数量较多时,可以通过分页上拉加载,增加页面首屏渲染速度。
扫码体验
前提条件
使用列表上拉加载的前提条件如下:
获取模板代码
下载 上拉加载 Demo.zip 文件,并解压至本地, 使用 IDE 打开。
示例代码
index.json
{
"defaultTitle": "上拉加载"
}
index.axml
<view class="schedule-container">
<scroll-view scroll-y="{{true}}" onScrollToLower="scrollMytrip" class="schedule-scroll">
<view a:for="{{list}}" class="schedule-detail">
<view class="schedule-place">{{item.title}}</view>
<view class="schedule-trainNumber padd font">{{item.remarksa}}</view>
<view class="schedule-time padd font">{{item.remarksb}}</view>
</view>
<view class="spinner" style="{{show ? '' : 'display:none'}}">
<view class="bounce1 bounce"></view>
<view class="bounce2 bounce"></view>
<view class="bounce3 bounce"></view>
<view style="margin:20rpx 0 0 20rpx;color:#666666;">加载中...</view>
</view>
</scroll-view>
</view>
index.acss
.schedule-container{
width: 100vw;
height: 100vh;
overflow: hidden;
}
.schedule-scroll {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
}
.spinner {
text-align: center;
height: 60rpx;
line-height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
}
.spinner .bounce {
margin-top: 20rpx;
width: 13rpx;
height: 21rpx;
display: inline-block;
animation-fill-mode: both;
margin-left: 13rpx;
transform: skewX(-15deg);
}
.spinner .bounce1 {
background: #108EE9;
animation: bouncedelay1 2.1s infinite linear;
}
.spinner .bounce2 {
background: #9DCDEF;
animation: bouncedelay2 2.1s infinite linear;
}
.spinner .bounce3 {
background: #EAECF3;
animation: bouncedelay3 2.1s infinite linear;
}
.spinner .spinner-word {
margin-top: 24rpx;
line-height: 40rpx;
height: 40rpx;
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
}
@keyframes bouncedelay1 {
0% {
background: #108EE9;
}
50% {
background: #9DCDEF;
}
100% {
background: #EAECF3;
}
}
@keyframes bouncedelay2 {
0% {
background: #9DCDEF;
}
50% {
background: #EAECF3;
}
100% {
background: #108EE9;
}
}
@keyframes bouncedelay3 {
0% {
background: #EAECF3;
}
50% {
background: #108EE9;
}
100% {
background: #9DCDEF;
}
}
.schedule-detail {
width: 100%;
height: 218rpx;
background-color: #ffffff;
margin-top: 20rpx;
}
.schedule-place , .schedule-trainNumber ,.schedule-time {
padding: 30rpx 30rpx 35rpx 30rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
font-size:32rpx;
color: #333333;
}
.schedule-money {
color:#E8541E;
}
.font {
color:#999999;
font-size: 28rpx;
}
.padd {
padding: 0rpx 30rpx 20rpx 30rpx;;
}
index.js
// mock列表数据
const mockData = [{
title: '列表1',
remarksa: '备注1',
remarksb: '备注2'
}, {
title: '列表2',
remarksa: '备注1',
remarksb: '备注2'
}, {
title: '列表3',
remarksa: '备注1',
remarksb: '备注2'
}, {
title: '列表4',
remarksa: '备注1',
remarksb: '备注2'
}, {
title: '列表5',
remarksa: '备注1',
remarksb: '备注2'
}, {
title: '列表6',
remarksa: '备注1',
remarksb: '备注2'
}];
// mock列表总数
const mockTotal = 60;
Page({
data: {
show: false, // 是否显示加载动画
page: 1, // 当前页数
list: [] // 页面List数据
},
onLoad() {
// 页面加载默认数据
this.mySchedulde();
},
/**
* scroll-view滑到底部触发事件
* @method scrollMytrip
*/
async scrollMytrip() {
try {
const { page, list, } = this.data;
// 判断是否还有数据需要加载
if (list.length < mockTotal) {
this.setData({ show: true });
const newPage = page + 1;
this.mySchedulde(newPage);
}
} catch (e) {
this.setData({ show: false });
console.log('scrollMytrip执行异常:', e);
}
},
/**
* 模拟请求服务端查询数据并渲染页面
* @method mySchedulde
* @param {int} page 分页,默认第1页
*/
async mySchedulde(page = 1) {
try {
let list = this.data.list;
// 模拟请求拿到数据进行更新data
setTimeout(() => {
let data = mockData;
for (let i = 0; i < data.length; i++) {
let newObj = { ...data[i], remarksa: `我是第${page}页` };
list.push(newObj);
}
this.setData({
list,
page,
show: false
});
}, 800);
} catch (e) {
console.log('mySchedulde执行异常:', e);
}
}
});