一、实现效果
二、实现步骤
主要实现功能:
页面导航并传参 上拉触底时加载下一页数据 下拉刷新列表数据
实现步骤
创建列表页面 动态设置页面标题 定义数据,发起请求获取数据 渲染数据并美化样式 实现上拉加载数据效果 对上拉触底进行节流处理 上拉触底请求数据前,判断数据是否加载完毕 下拉刷新处理数据 使用WXS处理手机号
三、具体代码
创建列表页面:在app.json的pages配置项新增shopList
"pages":[
"pages/home/home",
"pages/message/message",
"pages/contact/contact",
"pages/shopList/shopList"
],
动态设置页面标题 query 用来接收点击页面传递给shopList页面的参数,包括id和title。
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.setData({
query: options
});
this.getShoplist();
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
wx.setNavigationBarTitle({
title: this.data.query.title,
})
},
定义数据,发起请求获取数据
data: {
query: {},
shoplist: [],
page: 1, // 当前是第几页
pageSize: 10, // 每一页数据条数
total: 0, // 所有数据条数
isLoading: false
},
getShoplist(a) {
wx.request({
url: `https://applet-base-api-t.itheima.net/categories/${this.data.query.id}/shops`,
method: 'GET',
data: {
_page: this.data.page,
_limit: this.data.pageSize
},
success: (res) =>{
this.setData({
shoplist: [...this.data.shoplist, ...res.data],
total: res.header['X-Total-Count'] - 0
});
},
})
},
渲染数据并美化样式
// WXML 文件
<view wx:for="{{shoplist}}" wx:key="id" class="shop-item">
<view class="thumb">
<image src="{{item.images[0]}}" />
</view>
<view class="info">
<text>{{item.name}}</text>
<text>电话:{{item.phone}}</text>
<!-- <text>电话:{{item.phone}}</text> -->
<text>地址:{{item.address}}</text>
<text>营业时间:{{item.businessHours}}</text>
</view>
</view>
// WXSS 文件
.shop-item {
display: flex;
padding: 15rpx;
border: 1rpx solid #efefef;
margin: 15rpx;
box-shadow: 1rpx 1rpx 20rpx #ddd;
}
.thumb image {
width: 250rpx;
height: 250rpx;
vertical-align: middle;
margin-right: 15rpx;
}
.info {
display: flex;
flex-direction: column;
justify-content: space-around;
font-size: 24rpx;
}
.info text:nth-child(1) {
font-weight: bolder;
}
实现上拉加载数据效果 通过wx.showLoading(Object object)
实现,当数据没有加载出来,显示“数据加载中”,数据请求完成隐藏该效果。
getShoplist(a) {
// 展示loading效果
wx.showLoading({
title: '数据加载中...',
});
wx.request({
url: `https://applet-base-api-t.itheima.net/categories/${this.data.query.id}/shops`,
method: 'GET',
data: {
_page: this.data.page,
_limit: this.data.pageSize
},
success: (res) =>{
this.setData({
shoplist: [...this.data.shoplist, ...res.data],
total: res.header['X-Total-Count'] - 0
});
},
complete: ()=>{
// 隐藏loading效果
wx.hideLoading();
}
})
},
对上拉触底进行节流处理,分为以下几步:
在 data 中定义 isloading 节流阀。isloading 为布尔值,false 表示当前没有进行任何数据请求,可以请求, true 表示当前正在进行数据请求,重新触发的下一页请求都要被屏蔽。 在 getShopList() 方法中修改 isloading 节流阀的值。当开始发起请求时,调用 getShopList 时将节流阀设置 true,数据请求完成之后,在网络请求的 complete回调函数中,将节流阀重置为 false。 在 onReachBottom 中判断节流阀的值,从而对数据请求进行节流控制。如果节流阀的值为 true,则阻止当前请求。如果节流阀的值为 false,则发起数据请求。
Page({
/**
* 页面的初始数据
*/
data: {
query: {},
shoplist: [],
page: 1, // 当前是第几页
pageSize: 10, // 每一页数据条数
total: 0, // 所有数据条数
isLoading: false
},
getShoplist(a) {
this.setData({
isLoading: true
})
// 展示loading效果
wx.showLoading({
title: '数据加载中...',
});
wx.request({
url: `https://applet-base-api-t.itheima.net/categories/${this.data.query.id}/shops`,
method: 'GET',
data: {
_page: this.data.page,
_limit: this.data.pageSize
},
success: (res) =>{
this.setData({
shoplist: [...this.data.shoplist, ...res.data],
total: res.header['X-Total-Count'] - 0
});
},
complete: ()=>{
// 隐藏loading效果
wx.hideLoading();
this.setData({
isLoading: false
});
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.setData({
query: options
});
this.getShoplist();
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
wx.setNavigationBarTitle({
title: this.data.query.title,
})
},
// 重新发起数据请求 第一页
this.getShoplist(()=>{
wx.stopPullDownRefresh();
});
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
// 判断是否正在加载其他数据,节流
if (this.data.isLoading===true) {
return;
}
this.setData({
page: this.data.page + 1
})
this.getShoplist();
},
})
上拉触底请求数据前,判断数据是否加载完毕 page * pageSize >= total
即已展示的数据条数大于等于总条数,表示页面数据已经全部加载完毕,不再发起请求 并且调用wx.showToast(obj)
让页面显示“数据正在加载完毕”。
onReachBottom() {
// 判断是否还有下一页数据
if (this.data.pageSize * this.data.page >= this.data.total) {
return wx.showToast({
title: '数据加载完毕!',
icon: 'none'
})
}
// 判断是否正在加载其他数据,节流
if (this.data.isLoading===true) {
return;
}
this.setData({
page: this.data.page + 1
})
this.getShoplist();
},
下拉刷新处理数据 下拉刷新要重置数据,发起请求返回的是第一页的数据。请求数据后 还要调用函数 wx.stopPullDownRefresh();
关闭下拉刷新效果。
onPullDownRefresh() {
// 重置关键数据
this.setData({
page: 1,
shoplist: [],
total: 0
});
// 重新发起数据请求 第一页
this.getShoplist(()=>{
wx.stopPullDownRefresh();
});
},
使用WXS处理手机号
function splitPhone(str) {
if (str.length != 11) {
return str;
} else {
var arr = str.split('');
arr.splice(3, 0, '-');
arr.splice(8, 0, '-');
console.log(arr);
return arr.join('');
}
// return str;
}
module.exports = {
splitPhone: splitPhone
}
<view wx:for="{{shoplist}}" wx:key="id" class="shop-item">
<view class="thumb">
<image src="{{item.images[0]}}" />
</view>
<view class="info">
<text>{{item.name}}</text>
<text>电话:{{m1.splitPhone(item.phone)}}</text>
<!-- <text>电话:{{item.phone}}</text> -->
<text>地址:{{item.address}}</text>
<text>营业时间:{{item.businessHours}}</text>
</view>
</view>
<wxs src="../../utils/shoplist.wxs" module="m1"></wxs>
四、完整代码
shopList.wxml
文件
<!--pages/shopList/shopList.wxml-->
<view wx:for="{{shoplist}}" wx:key="id" class="shop-item">
<view class="thumb">
<image src="{{item.images[0]}}" />
</view>
<view class="info">
<text>{{item.name}}</text>
<text>电话:{{m1.splitPhone(item.phone)}}</text>
<!-- <text>电话:{{item.phone}}</text> -->
<text>地址:{{item.address}}</text>
<text>营业时间:{{item.businessHours}}</text>
</view>
</view>
<wxs src="../../utils/shoplist.wxs" module="m1"></wxs>
shopList.wxss
文件
/* pages/shopList/shopList.wxss */
.shop-item {
display: flex;
padding: 15rpx;
border: 1rpx solid #efefef;
margin: 15rpx;
box-shadow: 1rpx 1rpx 20rpx #ddd;
}
.thumb image {
width: 250rpx;
height: 250rpx;
vertical-align: middle;
margin-right: 15rpx;
}
.info {
display: flex;
flex-direction: column;
justify-content: space-around;
font-size: 24rpx;
}
.info text:nth-child(1) {
font-weight: bolder;
}
shopList.js
文件
// pages/shopList/shopList.js
Page({
/**
* 页面的初始数据
*/
data: {
query: {},
shoplist: [],
page: 1, // 当前是第几页
pageSize: 10, // 每一页数据条数
total: 0, // 所有数据条数
isLoading: false
},
getShoplist(a) {
this.setData({
isLoading: true
})
// 展示loading效果
wx.showLoading({
title: '数据加载中...',
});
wx.request({
url: `https://applet-base-api-t.itheima.net/categories/${this.data.query.id}/shops`,
method: 'GET',
data: {
_page: this.data.page,
_limit: this.data.pageSize
},
success: (res) =>{
this.setData({
shoplist: [...this.data.shoplist, ...res.data],
total: res.header['X-Total-Count'] - 0
});
// console.log(this.data.total);
// console.log(res);
// console.log(this.data.shoplist);
// console.log(this.data.total);
},
complete: ()=>{
// 隐藏loading效果
wx.hideLoading();
this.setData({
isLoading: false
});
a && a();
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.setData({
query: options
});
this.getShoplist();
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
wx.setNavigationBarTitle({
title: this.data.query.title,
})
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
// 重置关键数据
this.setData({
page: 1,
shoplist: [],
total: 0
});
// 重新发起数据请求 第一页
this.getShoplist(()=>{
wx.stopPullDownRefresh();
});
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
// 判断是否还有下一页数据
if (this.data.pageSize * this.data.page >= this.data.total) {
return wx.showToast({
title: '数据加载完毕!',
icon: 'none'
})
}
// 判断是否正在加载其他数据,节流
if (this.data.isLoading===true) {
return;
}
this.setData({
page: this.data.page + 1
})
this.getShoplist();
},
})
shopList.json
文件
{
"usingComponents": {},
"onReachBottomDistance": 200,
"enablePullDownRefresh": true,
"backgroundColor": "#efefef",
"backgroundTextStyle": "dark"
}
shopList.wxs
文件
function splitPhone(str) {
if (str.length != 11) {
return str;
} else {
var arr = str.split('');
arr.splice(3, 0, '-');
arr.splice(8, 0, '-');
console.log(arr);
return arr.join('');
}
// return str;
}
module.exports = {
splitPhone: splitPhone
}