18 changed files with 513 additions and 284 deletions
@ -0,0 +1,56 @@ |
|||||
|
<template> |
||||
|
<scroll-view scroll-y="true" upper-threshold="200" @scrolltolower="onScrollToBottom" scroll-with-animation="true"> |
||||
|
<view v-for="(item, idx) in showItems" :key="idx"> |
||||
|
<slot :item="item"> |
||||
|
</slot> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: "virtual-scroller", |
||||
|
data() { |
||||
|
return { |
||||
|
page: 1, |
||||
|
isInitEvent: false, |
||||
|
lockTip: false |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
items: { |
||||
|
type: Array |
||||
|
}, |
||||
|
size: { |
||||
|
type: Number, |
||||
|
default: 30 |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
onScrollToBottom(e) { |
||||
|
console.log("onScrollToBottom") |
||||
|
if (this.showMaxIdx >= this.items.length) { |
||||
|
this.showTip(); |
||||
|
} else { |
||||
|
this.page++; |
||||
|
} |
||||
|
}, |
||||
|
showTip() { |
||||
|
uni.showToast({ |
||||
|
title: "已滚动至底部", |
||||
|
icon: 'none' |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
showMaxIdx() { |
||||
|
return Math.min(this.page * this.size, this.items.length); |
||||
|
}, |
||||
|
showItems() { |
||||
|
return this.items.slice(0, this.showMaxIdx); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped></style> |
||||
@ -0,0 +1,20 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<web-view :src="linkUrl"></web-view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
linkUrl: '' |
||||
|
}; |
||||
|
}, |
||||
|
onLoad(options) { |
||||
|
this.linkUrl = decodeURIComponent(options.url); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,74 @@ |
|||||
|
<template> |
||||
|
<el-scrollbar ref="scrollbar"> |
||||
|
<div v-for="(item, idx) in items" :key="idx"> |
||||
|
<slot :item="item" v-if=" idx < showMaxIdx"> |
||||
|
</slot> |
||||
|
</div> |
||||
|
</el-scrollbar> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: "virtualScroller", |
||||
|
data() { |
||||
|
return { |
||||
|
page: 1, |
||||
|
isInitEvent: false, |
||||
|
lockTip: false |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
items: { |
||||
|
type: Array |
||||
|
}, |
||||
|
size: { |
||||
|
type: Number, |
||||
|
default: 30 |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
init() { |
||||
|
this.page = 1; |
||||
|
this.initEvent(); |
||||
|
}, |
||||
|
initEvent() { |
||||
|
if (!this.isInitEvent) { |
||||
|
let scrollWrap = this.$refs.scrollbar.$el.querySelector('.el-scrollbar__wrap'); |
||||
|
scrollWrap.addEventListener('scroll', this.onScroll); |
||||
|
this.isInitEvent = true; |
||||
|
} |
||||
|
}, |
||||
|
onScroll(e) { |
||||
|
const scrollbar = e.target; |
||||
|
// 滚到底部 |
||||
|
if (scrollbar.scrollTop + scrollbar.clientHeight >= scrollbar.scrollHeight - 30) { |
||||
|
if(this.showMaxIdx >= this.items.length ){ |
||||
|
this.showTip(); |
||||
|
}else{ |
||||
|
this.page++; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
showTip(){ |
||||
|
// 提示限制最多3秒显示一次 |
||||
|
if(!this.lockTip){ |
||||
|
this.$message.success("已到滚动到底部") |
||||
|
this.lockTip = true; |
||||
|
setTimeout(()=>{ |
||||
|
this.lockTip = false; |
||||
|
},3000) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
showMaxIdx() { |
||||
|
return Math.min(this.page * this.size, this.items.length); |
||||
|
} |
||||
|
}, |
||||
|
mounted(){ |
||||
|
this.initEvent(); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped></style> |
||||
Loading…
Reference in new issue