vue实现分页 上拉加载下拉刷新
最近写的项目需要用到分页,又没有引用什么库,只能手写一个。
由于没有思路,就搜了一波,还真找到了,但是直接拿过来又频频报错,所以自己按照搜出来的方法整理了一遍,可以直接用了。
下面这个是没有封装组件的样子,还有个封装组件的会单独贴出来。
<template>
<div>
<div class="header">
23213123123131321
</div>
<div class="my-scroll" @scroll.passive="onScroll($event)" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)" ref="myScroll">
<div class="scroll-top" :style="'height:'+top+'px'">
<div v-if="aspect==2">
<p v-if="state==6">下拉刷新</p>
<p v-if="state==2">松开刷新</p>
<p v-if="state==1">
<img :src="Load"/>刷新中
</p>
<p v-if="state==3">
<img :src="Load"/>刷新完成
</p>
</div>
</div>
<div class="scroll-list">
<div>
<ul>
<li v-for="(x,index) in list" :key="index">列表</li>
</ul>
</div>
<div class="scroll-bottom">
<p v-if="state==4"><img :src="Load"/>加载中</p>
<p v-if="state==5"><img :src="Load"/>加载完成</p>
<p v-if="state==7" class="no-more-data">没有更多了,我是有底线的</p>
</div>
</div>
</div>
</div>
</template>
<script>
import Load from '@/assets/loading1.gif'
export default {
data(){
return {
Load,
scrollState:true,
list:[],
page:{
counter:1,
pageStart:1,
pageEnd:1,
total:2,
},
pageX:0,
pageY:0,
state:0,
scrollPosition:0,
myScroll:null,
myScrollList:null,
top: 0,
aspect: 0, //1:向下 2:向上
listHeight:0,
}
},
mounted(){
this.myScroll = this.$refs.myScroll //获取滑条dom
this.myScrollList = this.myScroll.children[1] //获取列表dom
for(let i=0;i<1*30;i++){
this.list.push({})
}
},
methods:{
onRefresh(mun){ //刷新回调
setTimeout(()=>{
this.setState(3)
},500)
},
onPull(mun){ //加载回调
if(this.page.counter <= this.page.total){
setTimeout(()=>{
this.page.counter++
this.setState(5)
for(let i=0;i<10;i++){
this.list.push({})
}
},500)
}else{
this.setState(7)
}
},
getTop(y) {//滚动条位置
},
ScrollTop(top){ //修改滚动条位置
this.myScroll.scrollTop = top
},
// /*
// * 刷新中:1
// * 松开刷新:2
// * 刷新完成:3
// * 加载中:4
// * 加载完成:5
// * 下拉刷新:6
// * 没有更多:7
// */
setState(index){ //修改状态
this.state = index
if(index == 5||index == 3){
setTimeout(()=>{
this.state = 0
this.top = 0
},500)
}
},
touchStart(e){ //触摸事件
// console.log('触摸事件',e)
this.pageX = e.targetTouches[0].pageX
this.pageY = e.targetTouches[0].pageY
},
touchMove(e){ //触摸滑动事件
this.scrollPosition = this.myScroll.scrollTop //获取滚动条位置
console.log(this.scrollPosition)
if(this.scrollState && (e.targetTouches[0].pageY > this.pageY)){ //向上滑动
this.aspect = 2
if(this.myScroll.scrollTop==0){
let diff = e.targetTouches[0].pageY - this.pageY - this.scrollPosition
this.top = Math.pow(diff, 0.9)
let ranget = diff/document.body.clientHeight*100 //计算在屏幕上滑动了多少
if(ranget > 20){
this.state = 2
}else if(ranget < 15){
this.state = 6
}
e.preventDefault()
}
}else if(this.scrollState && this.state!=4){ //向上滑动
this.aspect = 1
}
},
touchEnd(e){
if(this.aspect == 2&&this.state == 2||this.state == 1){ //上拉处理
this.top = 100
this.state = 1
this.topCallback()
}else if(this.aspect == 2){
this.state = 0
this.top = 0
}
},
onScroll(e){
let listHeight = this.myScrollList.offsetHeight //列表总高度
let listScrollTop = e.target.scrollTop + this.myScroll.offsetHeight //当前滚动条位置
if(this.state == 0 && listHeight - listScrollTop < 100){
this.bottomCallback()
}
if(this.getScrollTop){ //返回X,Y
this.getScrollTop(e.target.scrollTop)
}
},
topCallback(){ //刷新回调
this.onRefresh(this.state)
},
bottomCallback(){ //加载回调
if(this.state != 7){
this.state = 4
this.onPull(this.state)
}
},
}
}
</script>
<style lang="scss" scoped>
.my-scroll{
margin-top: 100px;
background: #fff;
height: calc(100vh - 100px);
overflow: auto;
}
li{
font-size: 28px;
color: #666;
border-bottom: 1px solid #eee;
margin-left: 20px;
padding: 20px 0;
}
.scroll-top, .scroll-bottom{
background: #f4f4f4;
font-size: 28px;
text-align: center;
color: #999;
p{
padding: 20px 0;
}
img{
width: 40px;
vertical-align: -10px;
margin-right: 20px;
}
}
.no-more-data{
position: relative;
}
.no-more-data::before,.no-more-data::after{
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100px;
height: 2px;
background: #ccc;
}
.no-more-data::before{
left: 70px;
}
.no-more-data::after{
right: 70px;
}
.header{
position: fixed;
top: 0;
left: 0;
right: 0;
height: 100px;
z-index: 102;
background: #666;
}
</style>
只需要有个loading图片就可以用了
<template>
<div>
<div class="header">
23213123123131321
</div>
<div class="my-scroll" @scroll.passive="onScroll($event)" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)" ref="myScroll">
<div class="scroll-top" :style="'height:'+top+'px'">
<div v-if="aspect==2">
<p v-if="state==6">下拉刷新</p>
<p v-if="state==2">松开刷新</p>
<p v-if="state==1">
<img :src="Load"/>刷新中
</p>
<p v-if="state==3">
<img :src="Load"/>刷新完成
</p>
</div>
</div>
<div class="scroll-list">
<div>
<ul>
<li v-for="(x,index) in list" :key="index">列表</li>
</ul>
</div>
<div class="scroll-bottom">
<p v-if="state==4"><img :src="Load"/>加载中</p>
<p v-if="state==5"><img :src="Load"/>加载完成</p>
<p v-if="state==7" class="no-more-data">没有更多了,我是有底线的</p>
</div>
</div>
</div>
</div>
</template>
<script>
import Load from '@/assets/loading1.gif'
export default {
data(){
return {
Load,
scrollState:true,
list:[],
page:{
counter:1,
pageStart:1,
pageEnd:1,
total:2,
},
pageX:0,
pageY:0,
state:0,
scrollPosition:0,
myScroll:null,
myScrollList:null,
top: 0,
aspect: 0, //1:向下 2:向上
listHeight:0,
}
},
mounted(){
this.myScroll = this.$refs.myScroll //获取滑条dom
this.myScrollList = this.myScroll.children[1] //获取列表dom
for(let i=0;i<1*30;i++){
this.list.push({})
}
},
methods:{
onRefresh(mun){ //刷新回调
setTimeout(()=>{
this.setState(3)
},500)
},
onPull(mun){ //加载回调
if(this.page.counter <= this.page.total){
setTimeout(()=>{
this.page.counter++
this.setState(5)
for(let i=0;i<10;i++){
this.list.push({})
}
},500)
}else{
this.setState(7)
}
},
getTop(y) {//滚动条位置
},
ScrollTop(top){ //修改滚动条位置
this.myScroll.scrollTop = top
},
// /*
// * 刷新中:1
// * 松开刷新:2
// * 刷新完成:3
// * 加载中:4
// * 加载完成:5
// * 下拉刷新:6
// * 没有更多:7
// */
setState(index){ //修改状态
this.state = index
if(index == 5||index == 3){
setTimeout(()=>{
this.state = 0
this.top = 0
},500)
}
},
touchStart(e){ //触摸事件
// console.log('触摸事件',e)
this.pageX = e.targetTouches[0].pageX
this.pageY = e.targetTouches[0].pageY
},
touchMove(e){ //触摸滑动事件
this.scrollPosition = this.myScroll.scrollTop //获取滚动条位置
console.log(this.scrollPosition)
if(this.scrollState && (e.targetTouches[0].pageY > this.pageY)){ //向上滑动
this.aspect = 2
if(this.myScroll.scrollTop==0){
let diff = e.targetTouches[0].pageY - this.pageY - this.scrollPosition
this.top = Math.pow(diff, 0.9)
let ranget = diff/document.body.clientHeight*100 //计算在屏幕上滑动了多少
if(ranget > 20){
this.state = 2
}else if(ranget < 15){
this.state = 6
}
e.preventDefault()
}
}else if(this.scrollState && this.state!=4){ //向上滑动
this.aspect = 1
}
},
touchEnd(e){
if(this.aspect == 2&&this.state == 2||this.state == 1){ //上拉处理
this.top = 100
this.state = 1
this.topCallback()
}else if(this.aspect == 2){
this.state = 0
this.top = 0
}
},
onScroll(e){
let listHeight = this.myScrollList.offsetHeight //列表总高度
let listScrollTop = e.target.scrollTop + this.myScroll.offsetHeight //当前滚动条位置
if(this.state == 0 && listHeight - listScrollTop < 100){
this.bottomCallback()
}
if(this.getScrollTop){ //返回X,Y
this.getScrollTop(e.target.scrollTop)
}
},
topCallback(){ //刷新回调
this.onRefresh(this.state)
},
bottomCallback(){ //加载回调
if(this.state != 7){
this.state = 4
this.onPull(this.state)
}
},
}
}
</script>
<style lang="scss" scoped>
.my-scroll{
margin-top: 100px;
background: #fff;
height: calc(100vh - 100px);
overflow: auto;
}
li{
font-size: 28px;
color: #666;
border-bottom: 1px solid #eee;
margin-left: 20px;
padding: 20px 0;
}
.scroll-top, .scroll-bottom{
background: #f4f4f4;
font-size: 28px;
text-align: center;
color: #999;
p{
padding: 20px 0;
}
img{
width: 40px;
vertical-align: -10px;
margin-right: 20px;
}
}
.no-more-data{
position: relative;
}
.no-more-data::before,.no-more-data::after{
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100px;
height: 2px;
background: #ccc;
}
.no-more-data::before{
left: 70px;
}
.no-more-data::after{
right: 70px;
}
.header{
position: fixed;
top: 0;
left: 0;
right: 0;
height: 100px;
z-index: 102;
background: #666;
}
</style>

浙公网安备 33010602011771号