使用
1 赋值代码,封装成vue组件
2 安装这三个依赖
3 给引入的组件一个固定的高度。
<template>
<div ref="wrapper" class="wrapper">
<!-- wrapper 内的第一个dom 会被当做滚动内容,其他的dom 会被隐藏
所以要保证wrapper 内层只有一个dom
-->
<div>
<!-- 只有传递过来的pullDownRefresh == true 的时候才会渲染这里 -->
<div v-if='pullDownRefresh'>
<!-- 刷新前的提示 -->
<div class="beforeRefresh center" v-show="beforeRefresh">使劲往下拉</div>
<!-- 正在刷新 -->
<div class="downRefresh center" v-show="refreshing">
<div id="preloader_1">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
<!-- 刷新成功 -->
<div v-show="downSuccess" class="downSuccess center">刷新成功</div>
</div>
<slot></slot>
<!-- 1 upload 有固定的高并且一直存在,他里面的内容动态渲染
2 因为每次dom 的高度变化了,都要调用better-scroll 的refresh方法
更新内层的高度。
如果不调用的话,不会更新内层的高度,这样滚动的范围不变,新的dom
会被隐藏在窗口外面,不会随着滚动进入窗口.
-->
<!-- 只有传入pullUpLoad 的才会渲染这个固定的高度 -->
<div class="upload" v-if="pullUpLoad">
<span v-show="showUp&&!noData">
loading......
</span>
<span v-show='noData'>
我是有底线的_______!
</span>
</div>
</div>
</div>
</template>
<script type="text/ecmascript-6">
import BScroll from '@better-scroll/core'
import Pullup from '@better-scroll/pull-up'
import PullDown from '@better-scroll/pull-down'
BScroll.use(PullDown)
BScroll.use(Pullup);
export default {
data(){
return{
scroll:null,
showUp:false,
refreshing:false,
downSuccess:false,
beforeRefresh:true,
noData:false
}
},
props: {
pullUpLoad:{
type:Boolean,
default:true
},
// :pullDownRefresh={stop:50,threshold:90} 如果传过来的是这个那么直接放到构造器里面初始化
// :pullDownRefresh=false 如果是false,那么也是。
// stop 是下拉的回弹的悬停距离
// threshold 触发刷新的下拉距离。
pullDownRefresh:{
default:false
},
click: {
type: Boolean,
default: true
},
data: {
// type: Array,
default: null
},
},
mounted() {
setTimeout(() => {
this.initScroll()
}, 20)
},
methods: {
initScroll() {
if (!this.$refs.wrapper) {
return
}
this.scroll = new BScroll(this.$refs.wrapper, {
click: this.click,
pullDownRefresh:this.pullDownRefresh,
pullUpLoad:this.pullUpLoad,
probeType:2,//这个参数不生效,有bug
})
// 上拉
if (this.pullUpLoad) {
this.scroll.on('pullingUp', () => {
this.showUp = true;
this.$emit('pullUpLoad',(data)=>{
//手动调用结束上拉刷新,如果不调用的话,没法触发下一次
this.scroll.finishPullUp();
this.showUp = false;
// 无论传过来的是true 或者false
// 都会触发 upload 函数,执行函数里面的内容
// 只是页面的底部提示变成 “没有更多数据了”
if(data == true){
this.noData = true;
}else if(data == false){
this.noData = false;
}
});
})
}
// 下拉
if(this.pullDownRefresh){
let that = this;
that.scroll.on('pullingDown',()=>{
// 隐藏 “往下拉” 提示
// 显示 “正在刷新” 提示
this.refreshing=true;
this.beforeRefresh = false;
that.$emit('pullDownRefresh',()=>{
//隐藏 “正在刷新” 提示
// 显示 “刷新成功” 提示
this.refreshing=false;
this.downSuccess=true;
// 显示刷新成功后 500 ms后 再恢复顶部高度
setTimeout(that.scroll.finishPullDown(),500);
// 窗口回弹后300 ms 后恢复原来状态。
setTimeout(()=>{
this.downSuccess=false;
this.beforeRefresh = true;
},800)
})
})
}
// 把new 出来的对象传给父组件
this.$emit('getScroll',this.scroll);
},
// 初始化结束
refresh() {
// 相当于获取 this.scroll 然后在调用他里面的方法
this.scroll && this.scroll.refresh()
},
},//method 方法
watch: {
// 监听到新数据传过来,然后调用refresh 方法重新渲染内层和外层的高度。
data() {
setTimeout(() => {
this.refresh()
},30)
}
}
}
</script>
<style scoped lang="scss">
.wrapper{
overflow: hidden;
position: relative;
width: 100vw;
}
// 顶部下拉刷新框
// 这个高度要设置最好和scroll 初始化的时候设置的高度一致;
.center{
position:absolute;
transform:translateY(-50px);
text-align: center;
width: 100%;
line-height:50px;
height:50px;
// border: 1px solid red;
}
// 下面的上拉舒心图标外框
.upload{
height:70px;
border: 1px solid darkgoldenrod;
text-align: center;
padding-top: 20px;
}
// ----------上面的刷新图标,如果换成自己的可以删除--------------------
#preloader_1{
position: relative;
margin-left:calc(50% - 25px);
margin-top:20px;
}
#preloader_1 span{
display:block;
bottom:0px;
width: 9px;
height: 5px;
background:#9b59b6;
position:absolute;
animation: preloader_1 1.5s infinite ease-in-out;
}
#preloader_1 span:nth-child(2){
left:11px;
animation-delay: .2s;
}
#preloader_1 span:nth-child(3){
left:22px;
animation-delay: .4s;
}
#preloader_1 span:nth-child(4){
left:33px;
animation-delay: .6s;
}
#preloader_1 span:nth-child(5){
left:44px;
animation-delay: .8s;
}
@keyframes preloader_1 {
0% {height:5px;transform:translateY(0px);background:#9b59b6;}
25% {height:30px;transform:translateY(15px);background:#3498db;}
50% {height:5px;transform:translateY(0px);background:#9b59b6;}
100% {height:5px;transform:translateY(0px);background:#9b59b6;}
}
// ------------------------end--------------------------------
</style>
使用案例
<template>
<scroller class="scroll"
ref='wrapper'
:data='singMenu'
:pullUpLoad=true
@pullUpLoad='pullUpLoad'
:pullDownRefresh={stop:50}
@pullDownRefresh='downRefresh'
>
<div class="menuList">
</div>
</scroller>
</template>
<script>
import scroller from '@/util/components/BScroller.vue';
export default {
data() {
return {
singMenu: []
};
},
methods: {
pullUpLoad(finashLoad){
console.log("上拉刷新");
setTimeout(function(){
finashLoad(true);
console.log("上拉结束")
},2000)
},
downRefresh(finash){
setTimeout(()=>{
finash();
},2000)
}
},
components:{
scroller,
}
};
</script>
<style lang='scss' scoped>
.scroll{
height: 88vh;
border: 2px solid darkblue;
}
</style>