學習better-scroll與vue結合使用


better-scroll,移動端滾動場景需求的插件

例: 做一個上下滾動,左右兩邊關聯(滑動右側左側對應的類別顯示高亮,點擊左側的類別名稱右側滑動到對應的位置)

如圖:

 

 

分析:滑動右側的時候左側對應的類高亮,高亮顯示是通過current類來控制的,當右邊滑動到不同個類的時候,同時更新左側的current的顯示。

要做的事情: 1、current來設置當前高亮,2、要實時監聽scrollY,3、將右側每一個類的頂部位置記錄下來

根據滑動的位置scrollY,記錄的每個類的頂部,來計算當前下標

 

第一步:下載better-scroll  npm install better-scroll -s

在組件中引入這個庫  import BScroll from 'better-scroll'

currentIndex: 記錄左側滑塊到哪個類

scrollY: 上下滾動的距離

tops:存放右邊每一個類的初始位置

 

第二步:分別創建左右兩個滑動列表,注意創建滑動列表時需要后台異步請求完數據之后再創建,用到this.$nextTick(),此處無請求

此處用setTimeout代替延后加載

 

第三步: 將獲取當前scrollY的函數,和獲取右側top的函數提取出來,定義在method中

  1: 實現_initScrollY()

  

 

 2:實現_initTops()

  

  3:左聯右

    

  4:右聯左

    

 

 所有代碼

    

<template>
    <div id="linkagelr">
        <div class="head hf">
            head
        </div>
        <div class="content">
            <div class="left" ref="left">
                <ul ref="l_item">
                    <li v-for="(item, index) in left" :class="{current: currentIndex == index}" @click="selectItem(index, $event)">
                        <span class="left-item">{{item}}</span>
                    </li>
                </ul>
            </div>
            <div class="right" ref="right">
                <ul ref="r_item">
                    <li v-for="item in right" class="right-item right-item-hook">
                        <h4>{{item.name}}</h4>
                        <ul>
                            <li v-for="num in item.content">{{item.name+num}}</li>
                        </ul>
                    </li>
                </ul>
            </div>
        </div>
        <div class="foot hf">
            foot
        </div>
    </div>
</template>

<script>
    /*
    * 分析:滑動右側的時候左側對應的類高亮,高亮顯示是通過current類來控制的,當右邊滑動到不同個類的時候,同時更新左側的current的顯示。
    * 要做的事情: 1、current來設置當前高亮,2、要實時監聽scrollY,3、將右側每一個類的頂部位置記錄下來
    * 根據滑動的位置scrollY,記錄的每個類的頂部,來計算當前下標
    */

    //第一步:下載better-scroll  npm install better-scroll -s
    //在組件中引入這個庫
    import BScroll from 'better-scroll'
    
    export default{
        data(){
            return {
                left: ['mathematics','chinese','english','physic','chemistry','art','music','others'],
                right: [
                    {
                        name: 'mathematics',
                        content: ['1','2','3','4','5','6','7']
                    },
                    {
                        name: 'chinese',
                        content: ['3','4','5','6']
                    },
                    {
                        name: 'english',
                        content: ['1','2','3','4','5','6','7']
                    },
                    {
                        name: 'physic',
                        content: ['4','5','6','7']
                    },
                    {
                        name: 'chemistry',
                        content: ['1','2','3','4','5']
                    },
                    {
                        name: 'art',
                        content: ['4','5','6','7']
                    },
                    {
                        name: 'music',
                        content: ['1','2','3','4','5']
                    },
                    {
                        name: 'others',
                        content: ['1','2','3','4','5','6','7']
                    }
                ],
                currentIndex: 0,
                clickEvent: false,
                scrollY: 0,
                tops: [] //存放每一個類的初始位置
            }
        },
        //第二步:分別創建左右兩個滑動列表,注意創建滑動列表時需要后台異步請求完數據之后再創建,用到this.$nextTick(),此處無請求

        //第三步: 將獲取當前scrollY的函數,和獲取右側top的函數提取出來,定義在method中

        methods: {
            //第四步: 實現_initScrollY()
            _initScrollY(){
                // 創建左側滑動
                this.lefts = new BScroll(this.$refs.left, {
                    click: true  //滑動列表默認是沒有點擊的,必須加上這個才能觸發點擊事件
                })
                //創建右側滑動
                this.rights = new BScroll(this.$refs.right, {
                    probeType: 2 //這里可以取4個值,具體參考官方文檔
                })

                // 給右側綁定的BScroll綁定監聽事件,獲取滑動過程中的位置
                this.rights.on('scroll', (pos)=>{
                    this.scrollY = Math.abs(Math.round(pos.y))
                })

                //獲取停下來的位置
                // 給右側綁定的BScroll綁定監聽事件,獲取滑動結束時的位置
                this.rights.on('scrollEnd', (pos)=>{
                    this.scrollY = Math.abs(Math.round(pos.y))
                    console.log(this.scrollY)
                    for(let i=0;i<this.tops.length;i++){
                        if(this.scrollY>this.tops[i] && this.scrollY< this.tops[i+1]){
                            this.currentIndex = i
                            if(i > this.$refs.l_item.children.length - 3){
                                var tmp = i - (this.$refs.l_item.children.length - 3)
                                console.log(1);
                                //當滾動到倒數第2個位置時左側列表向上滾動一個距離
                                this.lefts.scrollToElement(this.$refs.l_item.children[tmp], 100, 0, 0)
                            }
                            if(i < this.$refs.l_item.children.length - 3){
                                //當滾動到第3個位置時左側列表向下滾動一個距離
                                this.lefts.scrollToElement(this.$refs.l_item.children[0], 100, 0, 0)
                            }
                        }
                    }
                })
            },

            //實現_initTops()
            _initTops(){
                var tops = [] //定義一個空數組
                let top = 0;
                tops[0] = 0 //第一個li的坐標為0

                var lis = this.$refs.r_item.children; //獲取到了每個li
                //Array.protoype.slice.call(lis) 將具有length屬性的對象轉成數組 lis可能是個對象
                Array.prototype.slice.call(lis).forEach((li, index)=>{
                    top = top + li.clientHeight //當前的位置=上一個的位置+這個的高度
                    tops.push(top);
                })

                this.tops = tops
            },

            selectItem(index, event){
                this.currentIndex = index
                this.clickEvent = true
                if(!event._constructed){
                    return
                }else{
                    let rightItems = this.$refs.right.getElementsByClassName('right-item-hook')
                    let el = rightItems[index]
                    this.rights.scrollToElement(el, 300)
                }
            },

            //nowIndex 右聯左
            nowIndex(scrollY){
                /*
                    如果滑動的位置在當前這個和下一個之間,返回的是這個的下標
                    如:tops=[0,5,12,18,23]
                        如果scrollY=4  -----返回0
                            scrollY=8  -----返回1
                */
                for(let i=0;i<this.tops.lenght;i++){
                    if(scrollY>this.tops[i] && scrollY< this.tops[i+1]){
                        this.currentIndex = i
                    }
                }
                
            }
        },
        mounted(){
            setTimeout(()=>{
                //獲取scrollY
                this._initScrollY()

                //獲取右側tops
                this._initTops()
            }, 20)
        },
        computed:{
        }
    }
</script>
<style>
    #linkagelr{
        width: 100%;
        height: 100%;
    }
    .hf{
        position: fixed;
        width: 16rem;
        height: 2rem;
        line-height: 2rem;
        font-size: .8rem;
        text-align: center;
        background: #333;
        color: #fff;
    }
    .head{
        top:0;
    }
    .foot{
        bottom:0;
    }
    .content{
        display: flex;
        position: fixed;
        top: 2rem;
        bottom: 2rem;
        width: 16rem;
        overflow:hidden;
        background:#eee;
    }
    .left{
        flex: 0 0 4rem;
        width: 4rem;
        background: #f3f5f7;
    }
    .left li{
        width: 4rem;
        height: 4rem;
        display: flex;
        justify-content: center;
        align-items: center;
        border-bottom: .1rem solid #17a2b8;
        font-size: .6rem;
    }
    .current{
        background: #ff0000;
        color: #fff;
    }
    .right{
        flex: 1;
    }
    .right-item li{
        width: 100%;
        height: 5rem;
        border-bottom: .2rem solid #ffff00;
    }
    .right-item h4{
        font-size: 1rem;
        background: #ffc107;
        padding: .3rem 0;
    }
    .right-item ul>li{
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: .6rem;
    }
</style>
View Code

 

橫向滑動與些類似

<template>
    <div class="pic-wrapper" ref='picWrapper'>
        <ul class="pic-list" ref='picList'>
            <li class="pic-item" ref="item" v-for="item in left"> 
                {{item}}
            </li>
        </ul>
    </div>
</template>

<script>
    import BScroll from 'better-scroll'
    const options = {
        scrollY: true
    }
    options.pullDownRefresh = {
        threshold: 50,
        stop: 20
    }
    export default{
        data(){
            return {
                left: ['mathematics','chinese','english','physic','chemistry','art','music','others']
            }
        },
        methods: {
            
        },
        mounted(){
            var that = this;
            setTimeout(function(){
                let width = 0;
                for(let i=0; i<that.left.length;i++){
                    width += that.$refs.item[i].getBoundingClientRect().width;
                    console.log(width);
                }
                that.$refs.picList.style.width = width + 'px'
            },20)
            
            this.$nextTick(() => {
                if(!this.picScroll){
                    this.picScroll = new BScroll(this.$refs.picWrapper,{
                        scrollX: true,
                        eventPassthrough: 'vertical'
                    })
                }else{
                    this.picScroll.refresh();
                }
            })
            
        }
    }
</script>
<style>
    .pic-wrapper{
        padding-bottom: .5rem;
        width: 16rem;
        overflow: hidden;
        position: fixed;
        top:0;
        left: 0;
    }
    .pic-list{
        font-size: .6rem;
        background:#007bff;
        white-space: nowrap;
        margin:0;
        height: 2rem;
    }
    .pic-item{
        display: inline-block;
        color: #fff;
        /*margin-right: .5rem;*/
        padding: .5rem;
        box-sizing: border-box;
    }
</style>
View Code

 

  完結~

  注:只為個人學習記錄使用

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM