基于better-scroll封装一个上拉加载下拉刷新组件
1.起因
上拉加载和下拉刷新在移动端项目中是很常见的需求,遂自己便基于better-scroll封装了一个下拉刷新上拉加载组件.
2.过程
better-scroll是目前比较好用的开源滚动库,提供很多灵活的api供我们开发各种实用的组件,文档地址(https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/#better-scroll),本次主要用到它提供的pullDownRefresh 和 pullUpLoad api 开启上拉加载和下拉刷新的功能,同时它还提供两个event用于发送请求,pullingUp会在一次上拉加载之后触发,pullingdown 会在一次下拉刷新之后触发,可以在这两个事件中请求数据.这里有一个坑就是,每次上拉或者下拉之后需要调用finishPullUp或finishPullDown来结束这些动作.另外better-scroll在ios系统上快速滚动可能会出现白屏的bug,而且当你滚动暂停的时候回出现抖动,这些可以通过修改配置项useTransition:false解决,better-scroll会开始以js帧动画来渲染滑动效果,以下是代码部分:
<template>
<div class="scroll" ref="wrapper"> <!-- 数据列表 -->
<div class="list-wrapper">
<slot name="content"></slot>
<!-- 上拉加载 start-->
<slot name="pullup">
<div class="pullup-wrapper" v-if="pullUpLoad">
<div class="before-trigger" v-if="!isPullUpLoad">
{{ pullupText }}
</div>
<div class="after-trigger" v-else>
<loading></loading>
</div>
</div>
</slot>
<!-- 上拉加载 end-->
</div> <!-- 下拉刷新start -->
<slot name="pulldown">
<div class="pulldown-wrapper" :style="pullDownStyle">
<div class="before-trigger" v-if="beforePullDown">
{{ pullDownText }}
</div>
<div class="after-trigger" v-else>
<loading v-if="isPullDown"></loading>
<div v-else>刷新成功</div>
</div>
</div>
</slot>
<!-- 下拉刷新end --> </div>
</template> <script>
import Bscroll from 'better-scroll';
import loading from '../loading/loading.vue';
export default {
componentName : 'scroll',
components:{
loading
},
data(){
return{
scroll : null,
isPullUpLoad : false, // 上拉正在加载中
pullUpDirty : true, // 是否有新数据
isPullDown : false, // 正在刷新
beforePullDown: true, // 未开始下拉刷新
pullDownStyle : {}
}
},
mounted(){
this.initScroll();
},
computed:{
pullupText(){
const moreText = this.pullUpLoad && this.pullUpLoad.more || '上拉加载更多';
const noMoreText = this.pullUpLoad && this.pullUpLoad.nomore || '没有更多数据了';
return this.pullUpDirty && moreText || noMoreText;
},
pullDownText(){
return this.pullDown && this.pullDown.refreshText || '下拉刷新';
}
},
methods:{
forceUpdate(dirty){
if(this.pullUpLoad && this.isPullUpLoad){
this.pullUpDirty = dirty;
this.isPullUpLoad = false;
this.finishPullUp();
this.refresh();
}else if(this.pullDown && this.isPullDown){
this.isPullDown = false;
setTimeout(()=>{ // 让刷新成功停留一段时间
this.finishPullDown();
this.refresh();
},500)
}
},
initScroll(){
if(!this.$refs.wrapper){
return
}
let options = {
probeType : this.probeType,
click : this.click,
startX : this.startX,
startY : this.startY,
tap : this.tap,
pullUpLoad: this.pullUpLoad,
pullDownRefresh: this.pullDown && { threshold: 50,stop : 50 }
} this.scroll = new Bscroll(this.$refs.wrapper, options); // 代理scrollEnd事件
if(this.scrollEnd){
this.scroll.on('scrollEnd',(pos)=>{
this.$emit('scrollEnd', pos)
})
}
// 代理scroll事件
if(this.onScroll){
this.scroll.on('scroll',(pos)=>{
console.log(pos.y);
let position = pos.y-50 >= 20 && 20 || pos.y-50;
this.$set(this.pullDownStyle, 'top', position + 'px')
this.$emit('scroll', pos);
})
}
// 代理pullingUp事件,在一次上拉加载的动作后.
if(this.pullUpLoad){
this.onPullingUp();
} // 代理pullingDown事件,在一次下拉刷新的动作后.
if(this.pullUpLoad){
this.onPullingDown();
}
},
onPullingUp(){
this.scroll.on('pullingUp',()=>{
this.isPullUpLoad = true;
this.$emit('pullingUp');
})
},
onPullingDown(){
this.scroll.on('pullingDown', ()=>{
this.beforePullDown = false;
this.isPullDown = true;
this.$emit('pullingDown');
})
},
refresh(){
this.scroll && this.scroll.refresh();
},
finishPullUp(){
this.scroll && this.scroll.finishPullUp();
},
finishPullDown(){
this.scroll && this.scroll.finishPullDown();
}
},
watch:{
list(){
// 列表有变化刷新,没有变化在父组件调用forceUpdate
this.forceUpdate(true);
},
pullDownStyle:{
handler(val){
if(val.top == '-50px'){
this.beforePullDown = true;
}
},
deep : true
}
},
props : {
list : { // 数据源
type : Array,
default(){
return []
}
},
startX : { // 横轴方向初始化位置
type : Number,
default : 0
},
startY : { // 纵轴方向初始化位置
type : Number,
default : 0
},
probeType : { // 实时派发滚动位置的等级
type : Number,
default : 3
},
click : { // 开启better-scroll派发的click事件
type : Boolean,
default : true,
},
tap : {
type : Boolean, // 开启better-scroll派发的tap事件
default : false
},
scrollEnd : { // 监听滚动到结束位置
type : Boolean,
default : false
},
pullDown : { // 是否开启下拉刷新
type : null,
default : false
},
pullUpLoad : { // 是否开启上拉加载
type : null,
default : false
},
onScroll : { // 监听滚动事件
type : Boolean,
default : true
}
} }
</script> <style scoped lang="scss">
.scroll{
width: 100%;
height: 100%;
overflow: scroll;
position: relative; }
.list-wrapper{
width: 100%;
min-height: 101%;
}
.pulldown-wrapper{
width: 100%;
height: 50px;
position: absolute;
display: flex;
align-items : center;
justify-content : center;
left: 0;
top: -50px;
z-index: 100;
}
.pullup-wrapper{
width: 100%;
height: 50px;
display: flex;
align-items : center;
justify-content : center;
}
</style>
基于better-scroll封装一个上拉加载下拉刷新组件的更多相关文章
- mui scroll和上拉加载/下拉刷新
mui中 scroll和上拉加载/下拉刷新同时存在会出现两个滚动条 把/* */ /* //mui页面鼠标拖动代码: mui('.mui-scroll-wrapper').scroll({ dec ...
- Vue mint ui用在消息页面上拉加载下拉刷新loadmore 标记
之前总结过一个页面存在多个下拉加载的处理方式,今天再来说一下在消息页面的上拉加载和下拉刷新,基本上每个app都会有消息页面,会遇到这个需求 需求:每次加载十条数据,上拉加载下拉刷新,并且没有点击查看过 ...
- 上拉加载下拉刷新控件WaterRefreshLoadMoreView
上拉加载下拉刷新控件WaterRefreshLoadMoreView 效果: 源码: // // SRSlimeView // @author SR // Modified by JunHan on ...
- APICloud上啦加载下拉刷新模块
apicloud有自带的上啦加载下拉刷新,当让也可以用第三方或者在模块库里面找一个使用 一.下拉刷新,一下代码写在 apiready = function (){} 里面 apiready = fun ...
- RecyclerView 上拉加载下拉刷新
RecyclerView 上拉加载下拉刷新 <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/teach_s ...
- 微信小程序上拉加载下拉刷新
微信小程序实现上拉加载下拉刷新 使用小程序默认提供方法. (1). 在xxx.json 中开启下拉刷新,需要设置backgroundColor,或者是backgroundTextStyle ,因为加载 ...
- Flutter上拉加载下拉刷新---flutter_easyrefresh
前言 Flutter默认不支持上拉加载,下拉刷新也仅仅支持Material的一种样式.Android开发使用过SmartRefreshLayout的小伙伴都知道这是一个强大的刷新UI库,集成了很多出色 ...
- React-Native 上拉加载下拉刷新
react-native 上下拉加载的控件效果都不好,找了半天没找到,正打算自已封装的时候,无意中找到了一个比较好的控件,大家看一下: react-native-refresh-list-view 这 ...
- js上拉加载下拉刷新
写在前边: 工作需要,使用ajax在原来的列表下边使用ajax请求后台数据,拼接在列表最下边,在github转了好久,发现了一个bug极多的js刷新插件,尝试了一个下午,就在快放弃的时候,发现下边有留 ...
随机推荐
- nyoj399-整除个数
整除个数 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 1.2.3- -n这n(0<n<=1000000000)个数中有多少个数可以被正整数b整除. 输入 ...
- [Noi2002]Savage
[Noi2002]Savage 数学题. 题解回去写(有个坑点) flag++ #include <cstdio> int n,m,c[25],p[29],l[29]; int exgcd ...
- UID和GID(详细说明)
一.UID(User Identify)中文用户ID,相当于身份证一样,在系统中是唯一的. 用户分类centos6超级用户 UID=0 root普通用户 UID=500起 oldboy虚拟用户 UID ...
- python第二周:数据类型、列表、字典
1.模块初识: sys模块: import sys print(sys.path) #path打印环境变量--> ['F:\\python学习\\projects\\s14\\day2', 'F ...
- pycaffe 配置
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50967820 本文将继续接着上一篇博客 ...
- php 文件夹 与 文件目录操作
php文件夹操作函数 string basename ( string path [, string suffix] )给出一个包含有指向一个文件的全路径的字符串,本函数返回基本的文件名.如果文件名是 ...
- JavaScript 中对变量和函数声明提前的演示样例
如题所看到的,看以下的演示样例(能够使用Chrome浏览器,然后F12/或者右键,审查元素.调出开发人员工具,进入控制台console输入)(使用技巧: 控制台输入时Shift+Enter能够中途代码 ...
- Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds. If the server requires
Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds. If the server requires ...
- 积跬步,聚小流------java信息生成图片
需求: 是在做证书的时候碰到的这个问题. 当时需求是能够进行在线打印证书,第一次进行的操作是直接打印html,并且已经排好版(用jqprint插件)进行打印.在打印时碰到了兼容的问题,另外因为背景图片 ...
- openssl之BIO系列之24---SSL类型的BIO
SSL类型的BIO ---依据openssl doc\crypto\bio_f_ssl.pod翻译和自己的理解写成 (作者:DragonKing, Mail: wzhah@263.net ,公布于:h ...