最近写的项目需要用到分页,又没有引用什么库,只能手写一个。
由于没有思路,就搜了一波,还真找到了,但是直接拿过来又频频报错,所以自己按照搜出来的方法整理了一遍,可以直接用了。
下面这个是没有封装组件的样子,还有个封装组件的会单独贴出来。
<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:
100
px;
background:
#fff;
height:
calc(
100
vh
-
100
px);
overflow:
auto;
}
li{
font-size:
28
px;
color:
#666;
border-bottom:
1
px
solid
#eee;
margin-left:
20
px;
padding:
20
px
0;
}
.scroll-top,
.scroll-bottom{
background:
#f4f4f4;
font-size:
28
px;
text-align:
center;
color:
#999;
p{
padding:
20
px
0;
}
img{
width:
40
px;
vertical-align:
-10
px;
margin-right:
20
px;
}
}
.no-more-data{
position:
relative;
}
.no-more-data
::before,
.no-more-data
::after{
content:
'';
position:
absolute;
top:
50
%;
transform:
translateY(
-50
%);
width:
100
px;
height:
2
px;
background:
#ccc;
}
.no-more-data
::before{
left:
70
px;
}
.no-more-data
::after{
right:
70
px;
}
.header{
position:
fixed;
top:
0;
left:
0;
right:
0;
height:
100
px;
z-index:
102;
background:
#666;
}
</
style>