需配合mint-ui使用
<template>
<div
class="list-view component"
v-infinite-scroll="loadMore"
infinite-scroll-disabled="isLoaded"
infinite-scroll-distance="10"
ref='listView'
@touchmove='touchmove($event)'
@touchstart='touchstart($event)'
@touchend='touchend($event)'
>
<div
class="loading-bar-top"
:class="{transition:isTouchEnd}"
:style="`transform: translate3d(0, ${loadingTop}px, 0)`"
>
<Spinner
color="#26a2ff"
:size='24'
class="list-view-spinner"
></Spinner>
</div>
<slot></slot>
</div>
</template>
<script>
import { Spinner } from 'mint-ui'
export default {
props: {
canHorizontal: {
type: Boolean,
default: false
}
},
components: { Spinner },
data() {
return {
loading: false,
loadingTop: 0,
isTouchEnd: false,
isLoaded: false,
refreshStatus: false
}
},
methods: {
touchstart(ev) {
this.isTouchEnd = false
if (ev.changedTouches.length !== 1) return
if (this.$refs.listView.scrollTop !== 0) return
const TOUCH = ev.changedTouches[0]
this.__startX = TOUCH.pageX
this.__startY = TOUCH.pageY
},
touchmove(ev) {
if (ev.changedTouches.length !== 1) return
if (this.$refs.listView.scrollTop !== 0) return
const TOUCH = ev.changedTouches[0]
const CURT_X = TOUCH.pageX
const CURT_Y = TOUCH.pageY
const IS_VERTICAL = Math.abs(CURT_X - this.__startX) < 20
const DISTANCE = CURT_Y - this.__startY
const top = Math.floor(DISTANCE * 0.6)
if (this.canHorizontal) {
if (!IS_VERTICAL) {
this.isTouchEnd = true
this.loadingTop = 0
} else {
this.loadingTop = top > 200 ? 200 : top
}
} else {
this.loadingTop = top > 200 ? 200 : top
}
},
touchend(ev) {
clearTimeout(this.__refreshTimer)
this.isTouchEnd = true
if (ev.changedTouches.length !== 1) return
if (this.$refs.listView.scrollTop !== 0) return
if (this.loadingTop > 170) {
this.loadingTop = 110
this.__refreshTimer = setTimeout(() => {
this.refresh()
}, 2e2)
} else {
this.loadingTop = 0
}
},
refresh() {
this.refreshStatus = true
this.$emit('refresh')
},
refreshed() {
this.refreshStatus = false
this.loadingTop = 0
},
loadMore() {
if (this.refreshStatus) return
if (this.$refs.listView.scrollTop === 0) return
this.$emit('loadMore')
},
loadMored() {
this.isLoaded = true
}
}
}
</script>
<style lang="less" scoped>
.list-view {
height: 100%;
width: 100%;
overflow-y: scroll;
position: relative;
.loading-bar-top {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
width: 100%;
top: -90px;
left: 0;
right: 0;
height: 50px;
z-index: 20;
&.transition {
transition: 0.2s ease-out;
}
.list-view-spinner {
background-color: #fff;
box-shadow: 0 0 0 8px #fff;
border-radius: 50%;
}
}
}
</style>