
頁面布局和樣式就不浪費時間了,直接上代碼了
ref="foodwrapper"  ,然后在函數內用this.$refs.menuwrapper獲取到dom。  然后在Ajax內執行_initScroll() 函數,這個時候需要注意兩點,第一使用bs插件的時候子容器的高度一定要大于父容器的高度,才會產生滾動效果。第二,我們要等dom結構完全加載結束在調用_initScroll()方法才會生效,vue的作者也為我們提供了方法,來判斷dom結構是否完全加載this.$nextTick(() => {}),click: true屬性用來設置可以進行點擊事件。  _initScroll() {                    this.meunScroll = new BScroll(this.$refs.menuwrapper, {                        click: true                    });                    this.foodScroll = new BScroll(this.$refs.foodwrapper, {                        click: true                    });                }這時候created應改為  created() {                this.classMap = ['decrease', 'discount', 'guarantee', 'invoice', 'special'];                this.$http.get('./data.json').then((res) => {                    if(res.status === ERR_OK) {                        res = res.body.goods;                        this.goods = res;                        //dom結構加載結束                        this.$nextTick(() => {                            this._initScroll();                        })                    }                });            },  下面實現左右聯動并且實現文本的高亮,左右聯動的基本原理其實我們計算出右側實時變化的y值,落到哪一個區間,我們就顯示那一個區間。首先我們要計算整體區間的一個高度,然后分別計算第一個區間的高度,第二個區間的高度,以此類推。然后將區間數存入一個定義好的數組。當我們在滾動的時候實時拿到y軸的高度,然后對比在哪一個區間,這樣我們就會得到一個區間的索引值去對應左側的菜品類別,最后我們用一個vue的class去綁定高亮文本。  定義一個方法在_initScroll下面,作為計算高度的方法叫做_calculateHeight () ,在定義一個listHeight:[]數組,存放獲取的高度。我們在定義一個food-list-hook類,用來被js選擇。不要忘記在created內調用函數。_calculateHeight () {        let foodList = this.$refs.foodwrapper.getElementsByClassName('food-list-hook');        let height = 0;        //把第一個高度送入數組        this.listHeight.push(height);        //通過循環foodList下的dom結構,將每一個li的高度依次送入數組        for(let i=0; i<foodList.length; i++){             let item = foodList[i]                height += item.clientHeight            this.listHeight.push(height);        }    },我們獲取到區間高度數組后,我們要實時獲取到右側的y值,和左側的索引值做一個對比,定義一個scrollY變量用來存放實時獲取的y值。bs插件為我們提供了一個實時獲取y值的方法,我們在初始化this.foodScroll的時候加一個·屬性probeType: 3,其作用就是實時獲取y值,相當于探針的作用。  我們在添加一個方法this.foodScroll.on('scroll',(pos) => {}),作用是實時滾動的時候把獲取到的位置給暴露出來。代碼如下。  methods: {                _initScroll() {                    this.meunScroll = new BScroll(this.$refs.menuwrapper, {                        click: true                    });                    this.foodScroll = new BScroll(this.$refs.foodwrapper, {                        click: true,                        //探針作用,實時監測滾動位置                        probeType: 3                    });                    //設置監聽滾動位置                    this.foodScroll.on('scroll', (pos) => {                        //scrollY接收變量                        this.scrollY = Math.abs(Math.round(pos.y));                    })                },                _calculateHeight() {                    let foodList = this.$refs.foodwrapper.getElementsByClassName('food-list-hook');                    let height = 0;                    //把第一個高度送入數組                    this.listHeight.push(height);                    //通過循環foodList下的dom結構,將每一個li的高度依次送入數組                    for(let i = 0; i < foodList.length; i++) {                        let item = foodList[i]                        height += item.clientHeight                        this.listHeight.push(height);                    }                },            }定義一個計算屬性computed,用來計算左側對應的i值,從而定位到左側邊欄的位置  computed:{    currentIndex () {        for(let i=0; i<this.listHeight.length; i++){            //判斷當currentIndex在height1和height2之間的時候顯示            let height1 = this.listHeight[i];            let height2 = this.listHeight[i+1];            //最后一個區間沒有height2            if(!height2 || (this.scrollY >= height1 && this.scrollY < height2)){                return i;            }        }        return 0;    },獲取到i后,在menu-item綁定一個class:class="{'current':currentIndex === index}",當currentIndex和menu-item對應的index相等時,設置current的樣式。這樣就可以左右聯動了。  最后實現左側點擊的功能。在左側的li下綁定一個selectMenu的點擊事件,并傳入索引值,這樣我們就可以知道點擊的是哪一個li  selectMenu (index,event) {//      自己默認派發事件時候(BScroll),_constructed被置為true,但是瀏覽器原生并沒有這個屬性        if (!event._constructed){            return;        }        //運用BScroll接口,滾動到相應位置        let foodList = this.$refs.foodwrapper.getElementsByClassName('food-list-hook');        //獲取對應元素的列表        let el = foodList[index];              //設置滾動時間        this.foodScroll.scrollToElement(el, 300);    },至此,我們就用bs插件完成了這個左右頁面聯動的效果,代碼會上傳到github,有興趣的可以下載下來看一看,大神務噴!完整的js代碼  <script type="text/javascript">        var ERR_OK = 200;        new Vue({            el: '.goods',            data() {                return {                    msg: 'goods',                    goods: [],                    listHeight: [],                    scrollY: 0,                }            },            created() {                this.classMap = ['decrease', 'discount', 'guarantee', 'invoice', 'special'];                this.$http.get('./data.json').then((res) => {                    if(res.status === ERR_OK) {                        res = res.body.goods;                        this.goods = res;                        //dom結構加載結束                        this.$nextTick(() => {                            this._initScroll();                            //計算高度                            this._calculateHeight();                        })                    }                });            },            computed: {                currentIndex() {                    for(let i = 0; i < this.listHeight.length; i++) {                        //判斷當currentIndex在height1和height2之間的時候顯示                        let height1 = this.listHeight[i];                        let height2 = this.listHeight[i + 1];                        //          console.log('height1:'+height1+','+'height2:'+height2)                        //最后一個區間沒有height2                        if(!height2 || (this.scrollY >= height1 && this.scrollY < height2)) {                            return i;                        }                    }                    return 0;                }            },            methods: {                selectMenu(index, event) {                    //      自己默認派發事件時候(BScroll),_constructed被置為true,但是瀏覽器原生并沒有這個屬性                    if(!event._constructed) {                        return;                    }                    //運用BScroll接口,滾動到相應位置                    let foodList = this.$refs.foodwrapper.getElementsByClassName('food-list-hook');                    //獲取對應元素的列表                    let el = foodList[index];                    this.foodScroll.scrollToElement(el, 300);                },                _initScroll() {                    this.meunScroll = new BScroll(this.$refs.menuwrapper, {                        click: true                    });                    this.foodScroll = new BScroll(this.$refs.foodwrapper, {                        click: true,                        //探針作用,實時監測滾動位置                        probeType: 3                    });                    //設置監聽滾動位置                    this.foodScroll.on('scroll', (pos) => {                        //scrollY接收變量                        this.scrollY = Math.abs(Math.round(pos.y));                    })                },                _calculateHeight() {                    let foodList = this.$refs.foodwrapper.getElementsByClassName('food-list-hook');                    let height = 0;                    //把第一個高度送入數組                    this.listHeight.push(height);                    //通過循環foodList下的dom結構,將每一個li的高度依次送入數組                    for(let i = 0; i < foodList.length; i++) {                        let item = foodList[i]                        height += item.clientHeight                        this.listHeight.push(height);                    }                },            }        })    </script>
新聞熱點
疑難解答