饿了么项目---8、关于iscoll的扩展 better scroll的使用----左右菜单联动(2)

本章重点:
- 如何使用better scroll的事件派发
- better scroll的滚动监听事件、如何滚动元素、如何实现左右联动的巧妙逻辑

一、效果图

饿了么项目---8、关于iscoll的扩展 better scroll的使用----左右菜单联动(2)_第1张图片

二、需求分析

  1. 分块: good.vue组件主要分为左侧菜单区、右侧内容区、底部购物车区
  2. 单侧联动之当右侧内容区滚动时需要滑动到左侧相应菜单块.
    • 使用better scroll 滚动监听事件,监听当前滚动的y轴坐标scrollY
    • 内容区每个块顶部的y轴坐标,组成数组 listHeight,与左侧的index一一对应上
    • 左侧菜单的index等于当前滑动内容的currentIndex时,currentMenu高亮css类生效。currentIndex为计算属性,根据scrollY与listHeight数组的当前与下一个坐标做对比,判断滚动在哪个区间,则currentIndex为listHeight数组的当前坐标的index。
  3. 单侧联动之点击左侧菜单区,右侧内容区滚动到相应区块
    • 使用better scroll为左侧 菜单派发click点击事件,事件函数传递当前菜单的index
    • 为右侧内容区注册节点==ref=’foodsWrapper’==,获取每个内容区的DOM对象==this.$refs.foodsWrapper.getElementsByClassName(‘food-list-hook’);==
    • 使用better scroll的APIthis.foodsScroll.scrollToElement(el, duration),直接滚动到当前内容区index的DOM对象

三、完整的该模块的代码如下:

<template>
 <div class="goods">
    <div ref='menuWrapper'>
        <div class='goodsMenu'>
            <div v-for='(item,index) in goods' class='Menu-item' :class='{currentMenu:currentIndex===index}' @click='menuClick(index,$event)'>
                <span class='itemText'><span v-show='item.type>0' class='h-iconJ' :class='classMap[item.type]'>span>{{item.name}}span>
            div> 
        div> 
    div>
    <div ref='foodsWrapper'>
        <div class='goodsLists'>
           <div class='listOne food-list-hook' v-for='item in goods'>
               <h1 class='listOneTitle'>{{item.name}}h1>
               <div class='foodsOne' :class='{boderBottom:item.foods.length>1}' v-for='list in item.foods'>
                    <cartcontrol :food ='list'>cartcontrol>
                    <div class='listImg'>
                        <img :src="list.image">
                    div>
                    <div class='goodInfo'>
                        <div class='goodsName'>{{list.name}}div>
                        <div class='goodsDesc'>{{list.description}}div>
                        <div class='goodsxs'><span>月售{{list.sellCount}}span><span>好评率{{list.rating}}%span>div>
                        <div class='foodsPrice'><span>{{list.price}}span><span class='old' v-show='list.oldPrice!=""'>{{list.oldPrice}}span>
                        div>
                    div>
                div>
            div>
        div>
    div>
    <cartshop :minPrice = 'seller.minPrice' :deliveryPrice = 'seller.deliveryPrice'>cartshop>
div>
template>

<script>
import BScroll from 'better-scroll';
import cartcontrol from '../cartcontrol/cartcontrol.vue';
import cartshop from '../cartcontrol/cartshop.vue';
export default {
    name: 'goods',
    components:{cartcontrol,cartshop},
    props: {
        seller:{
            type:Object
        }
    },
    data(){
        return{
       goods:[],//商品信息
       listHeight:[],//每个菜单将要滑动的height
       scrollY:0
        }
    },
    computed:{ 
        currentIndex:function(){
            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.scrollYreturn i
                }
            }
        }
    },
    created(){
        //左侧菜单图标信息
        this.classMap=['decrease_3','discount_3','guarantee_3','invoice_3','special_3'],
        //goods商品数据请求
        this.$http.get('/api/goods').then((response)=>{
          response = response.body;
          if(response.errno){
            this.goods =response.data;
            this.$nextTick(()=>{
              this._initScroll();
              this._calculateHeight();
            })
           }
        },(response)=>{
          console.log(response)
        });
    },
    methods:{
        //点击菜单显示右侧相应菜单
        menuClick(index,event){
            if(!event._constructed) return false;
            let foodLists = this.$refs.foodsWrapper.getElementsByClassName('food-list-hook');
            let el =foodLists[index];

            this.foodsScroll.scrollToElement(el, 500)
        },
        //初始化better-scroll
        _initScroll() {
            //获取better-scroll实例
            this.meunScroll = new BScroll(this.$refs.menuWrapper, {
                click:true
            });
            this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {
                click:true,
                probeType:3
            });
            this.foodsScroll.on('scroll',(pos)=>{
                this.scrollY =Math.abs(Math.round(pos.y));
            })
        },
          //获取右侧商品每个列表的y坐标,组成数组listHeight
        _calculateHeight() {
            let foodLists = this.$refs.foodsWrapper.getElementsByClassName('food-list-hook');
            //第一个列表坐标
            let height=0;
            this.listHeight.push(height);
            for(let i=0,len=foodLists.length;ilet item =foodLists[i];
                height += item.clientHeight;
                this.listHeight.push(height);
            }
        }
    }
}
script>
<style scope>
    .goods{
        position:absolute;
        display: flex;
        width:100%;
        bottom:46px;
        top:176.4px;
        overflow: hidden;
    }
    .goodsMenu{
        flex: 0,0,80px;
        width:80px;
        padding:0 12px;
        background-color:#f3f5f7;
        box-sizing:border-box;
    }
    .Menu-item{
        position:relative;
        display: table;
        width:100%;
        height:54px;
        font-size:0;
    }
    .Menu-item:after,
    .boderBottom:after{
        position:absolute;
        content: '';
        width:100%;
        bottom:0;
        left:0;
        border-top: 1px solid rgba(7,17,27,0.1); 
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
    .Menu-item:last-child:after,
    .boderBottom:last-child:after{
        border-top:none;
    }
    .currentMenu{
        background-color:#fff;
        color:#000;
        padding: 0 12px;
        margin: -1px 0 0 -12px;
        border:none;

    }
    .itemText{
        display: table-cell;
        font-size:12px;
        color:#07111B;
        font-weight: 200;
        line-height: 14px;
        vertical-align: middle;
    }
    .Menu-item .h-iconJ{
        display: inline-block;
        width:14px;
        height:14px;
        margin-right:4px;
        background-size:14px 14px;
    }
    .decrease_3{
        background-image: url('[email protected]');
    }
    .discount_3{
       background-image: url('[email protected]');
   }
   .guarantee_3{
       background-image: url('[email protected]');
   }
   .invoice_3{
       background-image: url('[email protected]');
   }
   .special_3{
       background-image: url('[email protected]');
   }
   /*右侧商品区*/
   .goodsLists{
       flex: 1;
   }
   /*一个菜单分类*/
   .listOne{
    width:100%;
}
/*分类名*/
.listOneTitle{
    width:100%;
    height:26px;
    line-height: 26px;
    border-left:2px solid #d9dde1;
    background-color:#f3f5f7;
    padding-left:14px;
    font-size:12px;
    color:rgb(147,153,159);
    box-sizing:border-box;
}
/*商品介绍*/
.foodsOne{
    position: relative;
    display:flex;
    margin:18px;
    font-size:0px;
    box-sizing:border-box;
}
.boderBottom {
    /*border-bottom:1px solid rgba(7,17,27,0.1);*/
    padding-bottom: 18px;
}
.boderBottom:last-child{
    /*border-bottom:none;*/
    padding-bottom: 0;
}
.cartcontrol{
    position: absolute;
    bottom:18px;
    right:0;
}
.listImg{
    flex:0,0,58px;
    display:inline-block;
    width:58px;
    height:58px;
    vertical-align: top;
}
.listImg img{
    width:100%;
    height:100%;
}
.goodInfo{
    flex:1;
    display:inline-block;
    margin:2px 0 0 10px;
}
.goodInfo .goodsName{
    font-size:14px;
    color:rgb(7,17,27);
    line-height: 14px;
}
.goodInfo .goodsDesc,
.goodInfo .goodsxs{
    font-size:10px;
    color:rgb(147,153,159);
    line-height: 12px;
    margin-top:8px;
}
.goodInfo .goodsxs span:first-child{
    margin-right:12px;
}
.goodInfo .foodsPrice{
    font-size:10px;
    color:rgb(240,20,20);
    font-weight: normal;
    line-height: 14px;
    margin-top:8px;
}
.goodInfo .foodsPrice .old{
    text-decoration:line-through;
    margin-left:8px;
    color:rgb(147,153,159);
}
        /*.goodCarts{
            width:100%;
            height:46px;
        }*/
    style>

你可能感兴趣的:(仿饿了么笔记)