簡單的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>

 

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