组件全部代码

<template>

<div class="goods">   <!--左侧区域-->    <div class="menu-wrapper" ref="left">        <ul class="menu">            <li class="menu-item border-bottom"                :class="{'current':currentIndex===index}"                v-for="(item,index) in dataLlist.goods"                :key="index"                @click="selectIndex(index,$event)"                ref="menuList"            >                <div class="text">                    <goods-icon v-show="item.type>0" :index="item.type" class="text-ico"></goods-icon>                    {{item.name}}                </div>            </li>        </ul>    </div>    <!--右侧区域-->    <div class="foods-wrapper" ref="right">        <ul>            <li class="food-list food-list-hook"                v-for="(item,index) in dataLlist.goods"                :key="index">                <!--标题区域-->                <h1 class="border-left">{{item.name}}</h1>                <ul>                    <li class="food-item border-bottom"                        v-for="(foodItem,index) in item.foods"                    >                        <div class="food-image">                            <img :src="foodItem.icon" alt="foodItem.name">                        </div>                        <div class="food-desc">                            <div class="title">{{foodItem.name}}</div>                            <div class="desc">{{foodItem.description}}</div>                            <div class="num">                                <div class="sellCount">月售{{foodItem.sellCount}}份</div>                                <div class="rating">好评率{{foodItem.rating}}%</div>                            </div>                            <div class="price">                                <div class="new-price">¥{{foodItem.price}}</div>                                <div class="old-price border-bottom" v-show="foodItem.oldPrice">¥{{foodItem.oldPrice}}</div>                            </div>                        </div>                    </li>                </ul>            </li>        </ul>    </div></div>

</template>

<script>

import Icon from '../../common/iconType/Icon';import BScroll from 'better-scroll'export default {    name: "Goods",    props:['dataLlist'],    data(){        return{            listHeight:[],            scrollY:0 ,//为了实现左右区域映射        }    },    computed:{        currentIndex(){  //这个返回的是下标,当这个currentIndex的值与goods的下标一致的时候,            // 左侧区域就会呈现高亮现象            for (let i = 0; i < this.listHeight.length; i++) {                let height1 = this.listHeight[i];                let height2 = this.listHeight[i + 1];                if (!height2 || (this.scrollY >= height1 && this.scrollY < height2)) {                    this._followScroll(i) //实现当滑动的时候,左侧隐藏的食物类型显示                    return i;                }            }            return 0;        }    },    created(){        //dataLlist数据是异步加载,直接用new BScroll时,dom可能还没有更新        this.$nextTick(()=>{ //this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行,使用$nextTick异步初始化Bscroll            this.meunScroll=new BScroll(this.$refs.left,{                click:true            });            this.foodScroll=new BScroll(this.$refs.right,{                probeType: 3 //可以派发scroll事件,检测到实时滚动的位置            });            this.foodScroll.on('scroll',(pos) =>{                //参数pos就是在右侧区域滑动的实时位置                //Math.round()取整数,Math.abs取绝对值                this.scrollY =Math.abs( Math.round(pos.y));            });            this._calculateHeight(); //这个方法为了获取每个商品类的最大区间的高度        })    },    methods:{        _followScroll(index) {            if(index > 0 ){                let menuList = this.$refs.menuList;                let el = menuList[index];                this.meunScroll.scrollToElement(el, 300, 0, -100);//better-scroll的scrollToElement方法滚动到指定位置            }           },        _calculateHeight(){  //这个方法为了获取每个商品类的最大区间的高度          let height = 0;          let foodLsit = this.$refs.right.getElementsByClassName('food-list-hook');          this.listHeight.push(height); //listHeight这个数组是用来存放右侧商品中每个类型商品的最大区间高度的集合          for(var i=0;i<foodLsit.length;i++){              let item = foodLsit[i];             //clientHeight代表元素的高度              height += item.clientHeight; //每个元素的高度等于自身高度加上上一个元素的高度              this.listHeight.push(height); //最终listHeight集合了所有li[类为food-list-hook]到最顶部的高度          }        },        selectIndex(index,ele){            //better-scroll 会禁止移动端的点击事件,需要重新派发,同时在PC端会点击两次,此处需要做判断            if(!ele._constructed){                //better-scroll的派发事件scroll的event和pc端浏览器的点击事件的event有个                // 属性区别_constructed,pc端浏览器的点击事件的event中是没有这个属性的                return;            }            let rightItem  =this.$refs.right.getElementsByClassName('food-list-hook');            let item = rightItem[index]; //找到相应的li            this.foodScroll.scrollToElement(item, 250)  //better-scroll的scrollToElement方法滚动到指定位置        }      //  scrollToElement(el, time, offsetX, offsetY, easing) //第一个值接收目标元素,第二个是滚动时间,第三第四个是相对于目标元素的偏移量。},    components:{       'goods-icon': Icon    }}

</script>

<style scoped lang="stylus">

@import "../../assets/stylus/mixin.styl"

.goods

position absolutetop 3.6rembottom .92remdisplay flexwidth: 100%overflow: hidden.menu-wrapper    flex 0 0 1.6rem    width 1.6rem    background-color #f3f5f7    .menu-item        height 1.08rem        display flex        align-items center        justify-content left        &.border-bottom::before             color rgba(7,17,27,.1)        .text            font-weight 200            font-size .24rem            line-height .28rem            margin  0 .24rem            .text-ico                  margin-right -.08rem                  vertical-align top;        &.current            font-size .24rem            line-height .28rem            color rgb(240,20,20)            background-color #ffffff.foods-wrapper    flex 1    .food-list        h1            width 100%            height .52rem            line-height .52rem            padding-left .28rem            background-color #f3f5f7            font-size .24rem            color rgb(147,153,159)            &.border-left::before                border-color #d9dde1                border-width .1rem       .food-item           display flex           padding .36rem           &:last-child.border-bottom               border none           .food-desc               margin-left .2rem               font-size .2rem               color rgb(147,153,159)               .title                   font-size:.28rem                   color rgb(7,17,27)                   margin-top .04rem                   line-height .28rem               .desc                   margin .15rem auto                   line-height:.28rem               .num                   display flex                   margin 0 0 .16rem 0                   .sellCount                         margin-right .24rem               .price                   display flex                   align-items center                   .new-price                       color rgb(220,20,60)                       font-weight  700                       line-height .48rem                       margin-right .16rem                       font-size .28rem                   .old-price                       &.border-bottom::before                            position absolute                            top: 25%;                            border-width: 0.08rem;

</style>

Vue项目中使用better-scroll实现菜单滑动功能

  1. 安装和在组件中引入better-scroll

 npm install better-scroll --save引入import BScroll from 'better-scroll' 【在组件中引入,在后续的export default中就可以直接使用封装好的better-scroll功能了】
  1. better-scroll实现的下面功能

在菜单中要实现点击左侧菜单的食品类型名称,右侧就会自动滑动到此食品类型下的所有食品;在右侧区域中滑动到食品类型下的所有食品区域下的时候,左侧菜单会出现相应的高亮效果

如何实现上面的功能:

第一:需要知道要在哪些区域间实现滑动

第二:通过new BScroll()获取要实现滑动的区域

           this.meunScroll=new BScroll(this.$refs.left);            this.foodScroll=new BScroll(this.$refs.right);                        

第三:上面代码在理论上应该在相应的区域都应该能滑动了,但是现实是并不能滑动

  原因是:数据的获取是异步获取的,在定义滑动区域的时候,也许数据还没有更新,这是this.meunScroll的高度可能就没有高度外部类goods的高度,这样就不会滑动。    解决的方法:this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行,使用$nextTick异步初始化Bscroll    this.$nextTick(()=>{ //this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行,使用$nextTick异步初始化Bscroll            this.meunScroll=new BScroll(this.$refs.left,{                click:true            });            this.foodScroll=new BScroll(this.$refs.right,{                probeType: 3 //可以派发scroll事件,检测到实时滚动的位置            });            this.foodScroll.on('scroll',(pos) =>{                //参数pos就是在右侧区域滑动的实时位置                //Math.round()取整数,Math.abs取绝对值                this.scrollY =Math.abs( Math.round(pos.y));            });            this._calculateHeight(); //这个方法为了获取每个商品类的最大区间的高度        })