微信小程式自身有下拉重新整理的動態效果,但是這個效果只針對page,如果需要只對其中的某個滾動的子元素做下拉的效果,是沒法實現的,當然還有scroll-view,但是scroll-view在到達頂部和底部的時候比較生硬,沒有回彈的效果,所以我就想有沒有方法能實現這個回彈的效果。
我試了以下三種方法
1.使用better-scroll和mpvue
使用better-scroll外掛,用vue的方式寫滾動列表,實現了簡單的下拉重新整理上拉載入,better-scroll本身就有滾動回彈的效果,寫完之後,在瀏覽器裡看是沒問題了,但是經過mpvue編譯成小程式之後,初始化better-scroll物件的時候直接報錯了,我估計是因為better-scroll有使用到dom物件,但是小程式裡面是沒有dom物件的,具體的原因我沒有深究。
2.使用小程式的movable-view和scroll-view實現列表
使用movable-view,裡面巢狀scroll-view,movable-view和scroll-view的寬高是一樣的,這樣使用的話是可以滾動的,但是在開發者工具裡面沒有回彈的效果,和直接使用scroll-view差不多,手機上倒是有滾動回彈的效果,這樣開發的時候就沒辦法用了。
3.動態計算movable-view的高度
使用movable-view,movable-view裡面只有一個直接子節點,一個普通的view,姑且稱這個view為content,content不給高度,靠裡面的元素來撐高,然後在onReady裡面獲取到content的高度,賦值給movable-view,是的movable-view的高度和content的高度一致,這樣就可以了。上拉載入和下拉重新整理主要是監聽change事件,判斷他的位置,當content的內容改變的時候,再重新獲取一下content的高度賦值給movable-view即可。但是這個還有點問題,就是不能在app.json中使用usingComponents,也不能在頁面的json檔案裡面使用這個屬性,也就是不能使用自定義元件。具體問題還不知道為什麼,可能是微信小程式的一個bug吧,使用了之後page的寬高和movable-view的位置會變得很奇怪。
下面是我的程式碼
<view class=`container`>
<movable-area class=`area`>
<movable-view class=`view` style="height: {{h}}px;" direction="vertical" inertia out-of-bounds>
<view class=`content`>
<view class=`box` wx:for="{{list}}" wx:key="{{index}}">{{index}}</view>
</view>
</movable-view>
</movable-area>
</view>
page {
width: 100%;
height: 100%;
}
.container {
width: 100%;
height: 100%;
}
.box {
width: 100%;
height: 200rpx;
background-color: #FFEE00;
}
.area {
width: 100%;
height: 100%;
}
.view {
width: 100%;
}
Page({
data: {
isReseting: false //正在回彈
},
onLoad: function() {
let list = [];
for (let i = 0; i < 10; i++) {
list.push(i);
}
this.setData({
list
})
},
onReady: function() {
const query = wx.createSelectorQuery();
query.select(`.area`).boundingClientRect(res => {
this.data.areaH = res.height;
}).exec();
this.refresh();
},
refresh: function() {
const query = wx.createSelectorQuery();
query.select(`.content`).boundingClientRect(res => {
this.setData({
h: res.height
});
}).exec();
},
change: function (e) {
if (e.detail.source === `out-of-bounds`) {
if (e.detail.y < (this.data.areaH - this.data.h - 10)) {
//到達下拉重新整理的條件
if (!this.data.isReseting) {
//控制在回彈錢不再觸發
this.data.isReseting = true;
let list = [];
for (let i = 10; i < 20; i++) {
list.push(i);
}
this.setData({
list: this.data.list.concat(list)
})
this.refresh();
}
} else if (e.detail.y === 0) {
this.data.isReseting = false;
}
}
}
})