7 changed files with 193 additions and 2 deletions
Unified View
Diff Options
-
2app.js
-
BINassets/home/icon-vehicle.png
-
164components/virtual-list/index.js
-
7components/virtual-list/index.json
-
20components/virtual-list/index.wxml
-
0components/virtual-list/index.wxss
-
2pages/home/index/index.wxml
@ -0,0 +1,164 @@ |
|||||
|
const util = require('../../utils/util') |
||||
|
const math = require('../../utils/math') |
||||
|
|
||||
|
Component({ |
||||
|
/** |
||||
|
* 组件样式隔离 |
||||
|
*/ |
||||
|
options: { |
||||
|
addGlobalClass: true, |
||||
|
multipleSlots: true // 支持多个slot
|
||||
|
}, |
||||
|
properties: { |
||||
|
height: { |
||||
|
type: Number, |
||||
|
value: 800 |
||||
|
}, |
||||
|
threshold: { // 下拉刷新阈值,下拉距离超过该值触发刷新
|
||||
|
type: Number, |
||||
|
value: 30 |
||||
|
}, |
||||
|
loading: { |
||||
|
type: Boolean, |
||||
|
value: true, |
||||
|
observer(value) { |
||||
|
if(value){ |
||||
|
this.reset() |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
finished: { |
||||
|
type: Boolean, |
||||
|
value: false |
||||
|
}, |
||||
|
text: { |
||||
|
type: String, |
||||
|
value: '到底啦~' |
||||
|
}, |
||||
|
size: { |
||||
|
type: Number, |
||||
|
value: 15 |
||||
|
}, |
||||
|
pageList: { |
||||
|
type: Array, |
||||
|
value: [], |
||||
|
observer(value) { |
||||
|
if (!Array.isArray(value)) { |
||||
|
return |
||||
|
} |
||||
|
this.setList(value[0]) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
lifetimes: { |
||||
|
ready: function() { |
||||
|
const query = wx.createSelectorQuery().in(this) |
||||
|
query.select('#scrollview').boundingClientRect().exec((res) => { |
||||
|
this.data.scrollH = res[0].height |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 组件的初始数据 |
||||
|
*/ |
||||
|
data: { |
||||
|
current: 1, |
||||
|
headerHeight: 0, |
||||
|
bottomHeight: 0, |
||||
|
// pageList: [], // 每一页数据
|
||||
|
visiblist: [], // visible: false,// 当前是否显示
|
||||
|
pageHeight: [], // 每一页高度
|
||||
|
scrollH: 0,// 滚动框高度
|
||||
|
requesting: false |
||||
|
}, |
||||
|
/** |
||||
|
* 组件的方法列表 |
||||
|
*/ |
||||
|
methods: { |
||||
|
reset: function(){ |
||||
|
this.setData({ current: 1, loading: true, finished: false, headerHeight: 0, bottomHeight: 0, pageList: [], pageHeight: [] }) |
||||
|
}, |
||||
|
setList: function(listData){ |
||||
|
this.data.requesting = false |
||||
|
if (!Array.isArray(listData)) { |
||||
|
return |
||||
|
} |
||||
|
if (listData.length < this.data.size) { |
||||
|
this.data.finished = true |
||||
|
} |
||||
|
this.data.current = this.data.current + 1 |
||||
|
if (Array.isArray(listData) && listData.length > 0) { |
||||
|
let pageHeight = this.data.pageHeight, visiblist = this.data.visiblist; |
||||
|
let nowList = `pageList[${this.data.pageList.length - 1}]` |
||||
|
visiblist.push(true) |
||||
|
pageHeight.push({ |
||||
|
top: 0, // 顶部在scroll里的高度
|
||||
|
height: this.data.virtualHeight, // 高度
|
||||
|
bottom: this.data.virtualHeight, // 底部在scroll里的高度
|
||||
|
}) |
||||
|
this.data.pageHeight = pageHeight |
||||
|
this.setData({ [nowList]: listData, visiblist, finished: this.data.finished }) |
||||
|
console.log(this.data.pageList.length) |
||||
|
console.log(visiblist.length) |
||||
|
console.log(this.data.pageHeight.length) |
||||
|
this.initPageHeight(this.data.current - 2) |
||||
|
} |
||||
|
}, |
||||
|
// 初始化首页高度
|
||||
|
initPageHeight: function(index) { |
||||
|
const query = wx.createSelectorQuery().in(this) |
||||
|
query.select(`#listPageId${index}`).boundingClientRect().exec((res) => { |
||||
|
let pageHeight = this.data.pageHeight; |
||||
|
pageHeight[index] = { |
||||
|
top: index > 0 ? pageHeight[index - 1].bottom + 1 : 0, // 顶部在scroll里的高度
|
||||
|
height: res[0].height, |
||||
|
bottom: index > 0 ? math.plus(pageHeight[index - 1].bottom + 1, res[0].height) : res[0].height // 底部在scroll里的高度
|
||||
|
} |
||||
|
this.data.pageHeight = pageHeight |
||||
|
}) |
||||
|
}, |
||||
|
bindscroll: util.throttle(function (e) { |
||||
|
// 实现虚拟列表
|
||||
|
let pageList = this.data.pageList |
||||
|
let visiblist = this.data.visiblist |
||||
|
let headerHeight = this.data.headerHeight |
||||
|
let bottomHeight = this.data.bottomHeight |
||||
|
this.data.pageHeight.forEach((item, index) => { |
||||
|
// 手指上滑
|
||||
|
if (e.detail.deltaY < 0 && item.bottom < math.minus(e.detail.scrollTop, 10) && visiblist[index] && pageList[index + 2]) { |
||||
|
// 隐藏头部
|
||||
|
visiblist[index] = false; |
||||
|
headerHeight += item.height; |
||||
|
// 显示底部
|
||||
|
if (!visiblist[index + 2]) { |
||||
|
visiblist[index + 2] = true; |
||||
|
// console.log('index>>>' + index)
|
||||
|
// console.log(pageList.length)
|
||||
|
// console.log(visiblist.length)
|
||||
|
// console.log(this.data.pageHeight.length)
|
||||
|
bottomHeight -= this.data.pageHeight[index + 2].height |
||||
|
} |
||||
|
} |
||||
|
// 手指下滑
|
||||
|
if (e.detail.deltaY > 0 && item.top > math.plus(e.detail.scrollTop, math.plus(this.data.scrollH, 10)) && visiblist[index] == true && pageList[index - 2]) { |
||||
|
// 隐藏头部
|
||||
|
visiblist[index] = false; |
||||
|
bottomHeight += item.height; |
||||
|
if (!visiblist[index - 2]) { |
||||
|
// 显示底部
|
||||
|
visiblist[index - 2] = true; |
||||
|
headerHeight -= this.data.pageHeight[index - 2].height |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
this.setData({ visiblist, headerHeight, bottomHeight }) |
||||
|
}, 100), |
||||
|
scrolltolower: function(){ |
||||
|
if (this.data.requesting || this.data.finished) { |
||||
|
return |
||||
|
} |
||||
|
this.data.requesting = true |
||||
|
this.triggerEvent('loadmore') |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
@ -0,0 +1,7 @@ |
|||||
|
{ |
||||
|
"component": true, |
||||
|
"usingComponents": { |
||||
|
"van-divider": "/components/divider/index", |
||||
|
"van-loading": "/components/loading/index" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
<scroll-view id="scrollview" scroll-y style="height:{{height}}rpx" bindscrolltolower="scrolltolower" bindscroll="bindscroll" lower-threshold="80"> |
||||
|
<view class="list-empty" style="height:{{height}}rpx" wx:if="{{!pageList.length}}"> |
||||
|
<view style="margin-bottom:24px" wx:if="{{loading}}"> |
||||
|
<van-loading type="spinner" size="32" /> |
||||
|
</view> |
||||
|
<image class="img-empty" src="/assets/image/list_empty.png" wx:else></image> |
||||
|
<view class="text-empty">{{loading? '正在加载' : '暂无数据'}}</view> |
||||
|
</view> |
||||
|
<view style="height: {{ headerHeight }}px;"></view> |
||||
|
<view wx:for="{{pageList}}" wx:for-item="element" wx:for-index="page" wx:key="page" id="listPageId{{page}}" wx:if="{{visiblist[page]}}"> |
||||
|
<view wx:for="{{element}}" wx:key="index"> |
||||
|
<item item="{{item}}"></item> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view style=" height: {{bottomHeight}}px;"></view> |
||||
|
<van-divider content-position="center" wx:if="{{ pageList.length >= 1}}" custom-style="padding:0rpx 120rpx"> |
||||
|
<van-loading type="spinner" size="16" wx:if="{{!finished}}" /> |
||||
|
<text class="text-sm" style="margin-left:8rpx">{{finished?'到底啦~':'加载中...'}}</text> |
||||
|
</van-divider> |
||||
|
</scroll-view> |
||||
Write
Preview
Loading…
Cancel
Save