前言
最近在做微信小程序项目中,有一个功能就是做一个商品列表分页限流然后实现上拉加载下拉刷新功能,遇到了一个使用scroll-viwe组件下拉刷新事件始终不触发问题,网上很多说给scroll-view设置一个高度啥的就可以解决,有些人设置了高度也不触发,所以在下就研究了一波这个scroll-view的触发机制。
一、scroll-view
可滚动视图区域。使用竖向滚动时,需要给scroll-view一个固定高度,通过 WXSS 设置 height。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。
两个属性是作为上拉加载下拉刷新触发事件
scroll-view属性bindrefresherrefresh
:自定义下拉刷新被触发
scroll-view属性bindscrolltolower
:滚动到底部/右边时触发
官网文档:https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html
二、上拉加载下拉刷新
提示:以下是本篇文章正文内容,下面案例可供参考
1. wxml代码
<scroll-view
id="scrollView" scroll-y="true" style="height: {{windowHeight}}px;"
refresher-enabled="{{true}}"
refresher-threshold="{{100}}"
refresher-default-style="white"
refresher-background="rgb(211, 234, 248)"
refresher-triggered="{{triggered}}"
bindrefresherrefresh="onRefresh"
bindscrolltolower="loadMore"
>
<view class="fruit-list" wx:for="{{fruits}}" wx:key="id">
<view class="fruit-item">
<image src="{{requestUrl}}{{item.imageUrl}}"></image>
<view class="mid">
<text style="font-weight: bold;">{{item.name}}</text>
<text style="color: rgb(146, 146, 146);">库存{{item.stock}}</text>
<text style="font-weight: bold;">¥{{item.price}}</text>
</view>
<button>选择</button>
</view>
</view>
</scroll-view>
2. wxcc代码
.fruit-item {
display: flex;
justify-content: center;
align-items: center;
}
.fruit-item view {
display: flex;
flex-direction: column;
font-size: 9px;
flex: 2;
align-items: flex-start;
justify-content: center;
line-height: 30px;
}
.fruit-item image {
height: 100px;
width: 100px;
border-radius: 5px;
margin:10px;
flex: 3;
}
.fruit-item button {
background-color: rgb(219, 207, 137);
width: 40px;
height: 20px;
font-size: 8px;
flex: 1;
line-height: 5px;
}
.mid :first-child{
width: 70px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
3. 下拉刷新bindrefresherrefresh : onRefresh
下拉刷新事件定义
onRefresh() {
// 自己定义刷新事件
var self = this;
// 自己定义刷新事件
self.setData({
triggered: true, // 将triggered属性设置为true,表示下拉刷新已经被触发
})
wx.showToast({
title: "刷新成功"
})
setTimeout(function () {
self.setData({
triggered: false, // 将triggered属性设置为false,表示下拉刷新已完成
})
console.log('下拉刷新已完成');
}, 3000);
}
4. 上拉加载
scroll-view触发的条件
触底事件不触发有以下情况:
- scroll-view没有设置高度或者高度设置太高导致 item总高度 < scroll-view高度下拉过程中触不到底
- scroll-view容器中的item没有设置高度导致 item总高度<scollview高度
注意
:如果scroll-view高度 < item总高度且值小于1~4px也是不触发的要大于5px这样才会触发,
例如:scroll-view高度为480px,item总高度为480-484px不会触发
解决方案:
- scroll-view设置高度100vh;
- item设置一个适合的高度
100vh
是一个在网页开发中常用的单位,表示相对于视窗(viewport)高度的百分比。具体来说,它等于视窗高度的百分之一百。在大多数情况下,该单位用于设置元素的高度或最小高度,以便使其充满整个视窗高度。
例如,如果视窗高度为600像素,那么使用"100vh"将会等于600像素。这样,你可以通过将元素的高度设置为"100vh",使其完全填充整个视窗高度。这在创建全屏幻灯片、背景图像或需要完全占据视窗的元素时非常有用。
下拉刷新bindrefresherrefresh : onRefresh下拉刷新事件定义
// 下拉刷新
onRefresh() {
var self = this;
this.setData({
triggered: true, // 将triggered属性设置为true,表示下拉刷新已经被触发
})
this.requestFruitList(this.data.flag, 1, function (data) {
// 处理响应数据,并将新的数据覆盖原有数据
this.setData({
fruits: data.fruits,
allPage: data.totalPages,
curPage: 1,
triggered: false, // 将triggered属性设置为false,表示下拉刷新已完成
})
wx.showToast({
title: "刷新成功"
})
}.bind(this), function (err) {
// 处理请求失败情况
console.error(err);
wx.showToast({
title: "刷新失败,请重试"
})
}.bind(this));
}
源码:
const app = getApp()
Page({
data: {
requestUrl: app.globalData.baseUrl,
types: [{
id: 1,
title: "鲜果现切"
}, {
id: 2,
title: "国产零食"
}, {
id: 3,
title: "特产零食"
},
{
id: 4,
title: "肉类蛋食"
}, {
id: 5,
title: "特色小吃"
}, {
id: 6,
title: "牛奶乳品"
},
{
id: 7,
title: "水果捞吧"
}, {
id: 8,
title: "当即热销"
}, {
id: 9,
title: "蔬菜鲜卖"
}
],
fruits: [{
id: 1,
name: "哈密瓜",
price: 29,
stock: 100,
imageUrl: "/images/ls.jpg"
}, {
id: 2,
name: "哈密瓜",
price: 29,
stock: 100,
imageUrl: "/images/ls.jpg"
},
{
id: 3,
name: "哈密瓜",
price: 29,
stock: 100,
imageUrl: "/images/ls.jpg"
}, {
id: 4,
name: "哈密瓜",
price: 29,
stock: 100,
imageUrl: "/images/ls.jpg"
}
],
flag: 1,
triggered: false, // 设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发
allPage: 1, // 总页数
curPage: 1, // 当前页数
windowHeight: null
},
// 上拉到底部触发
loadMore: function () {
console.log("加载更多");
var self = this;
// 为最后一页
if (self.data.curPage == self.data.allPage) {
wx.showToast({
title: '没有更多了',
})
} else {
setTimeout(function () {
console.log("加载更多");
var tempCurPage = self.data.curPage;
tempCurPage++;
self.setData({
curPage: tempCurPage
})
self.requestFruitList(self.data.flag, self.data.curPage, function (data) {
// 处理响应数据,并将新的数据添加到原有数据之后
var newFruits = self.data.fruits.concat(data.fruits);
self.setData({
fruits: newFruits,
allPage: data.totalPages
});
}, function (err) {
// 处理请求失败情况
console.error(err);
});
}, 300)
}
},
// 下拉刷新
onRefresh() {
var self = this;
this.setData({
triggered: true, // 将triggered属性设置为true,表示下拉刷新已经被触发
})
this.requestFruitList(this.data.flag, 1, function (data) {
// 处理响应数据,并将新的数据覆盖原有数据
this.setData({
fruits: data.fruits,
allPage: data.totalPages,
curPage: 1,
triggered: false, // 将triggered属性设置为false,表示下拉刷新已完成
})
wx.showToast({
title: "刷新成功"
})
}.bind(this), function (err) {
// 处理请求失败情况
console.error(err);
wx.showToast({
title: "刷新失败,请重试"
})
}.bind(this));
},
switchNav: function (e) {
var page = this;
var id = e.target.id;
if (this.data.currentTab == id) {
return false;
} else {
page.setData({
currentTab: id
});
}
page.setData({
flag: id,
curPage: 1
});
this.requestFruitList(id, page.data.curPage, function (data) {
// 处理响应数据
page.setData({
fruits: data.fruits,
allPage: data.totalPages
});
}, function (err) {
// 处理请求失败情况
console.error(err);
});
},
requestFruitList: function (typeId, curPage, successCallback, failCallback) {
wx.request({
url: this.data.requestUrl + '/fruit?typeId=' + typeId + '&pageNum=' + curPage,
method: 'GET',
success(res) {
console.log(res.data);
// 调用成功回调函数,并将响应数据作为参数传递
successCallback(res.data);
},
fail(err) {
console.error(err);
// 调用失败回调函数,并将错误信息作为参数传递
failCallback(err);
}
})
},
onLoad: function (options) {
var id = options.id; // 获取传递的参数
console.log('接收到的id参数为:' + id);
var page = this;
page.setData({
flag: id
})
this.requestFruitList(id, page.data.curPage, function (data) {
// 处理响应数据
page.setData({
fruits: data.fruits,
allPage: data.totalPages
});
}, function (err) {
// 处理请求失败情况
console.error(err);
});
// 获取屏幕高度
wx.getSystemInfo({
success: function (res) {
page.setData({
windowHeight: res.windowHeight
})
console.log('屏幕高度:', res.windowHeight);
}
})
}
})