简单的vue scroll 组件

使用

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>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章