实现右侧食物列表滚动,左侧菜单栏显示对应分类
原理:计算右侧商品栏每个类别商品的总高度,将他们存入一个数组,左侧的菜单栏每个分类的索引取自这个数组,比如左侧index为0的时候,对应展示右侧的是第一个分类的商品,index为1时,对应展示右侧的是第二个分类的商品,根据better-scroll监听到页面的滚动的位置,当页面滚动位置介于第i类和i+1类商品高度区间,返回对应的索引值i,依次类推,实现联动
html:
<!--左侧菜单栏-->
<div class="menu-wrapper" ref="menuWrapper">
<ul>
<li v-for="(item,index) of goods" :key="index" class="menu-item" :class="{'current':currentIndex===index}" @click="selectMenu(index,$event)">
省略部分代码
</li>
</ul>
</div>
<!--右侧食物列表栏-->
<div class="goods-wrapper" ref="foodsWrapper">
<ul>
<li v-for="(item,index) of goods" :key="index" class="food-list" ref="foodList">
<h1 class="title">{{item.name}}</h1>
<ul>
<li v-for="(food,index) of item.foods"
:key="index"
class="food-item"
@click="selectFood(food,$event)"
>
<div class="content">
<h2 class="name">{{food.name}}</h2>
<p class="desc">{{food.description}}</p>
<div class="extra">
<span class="sell-count">月售{{food.sellCount}}份</span><span class="rating">好评率{{food.rating}}%</span>
</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
js
methods:{
// 初始化滚动
_initSroll () {
this.menuScroll = new Bscroll(this.$refs.menuWrapper, {click: true})
// bsscroll会阻止一些默认的事件的触发,所以需要给事件加上true, probeType,BScroll滚动时,能实时告诉我们滚动的位置
this.foodsScroll = new Bscroll(this.$refs.foodsWrapper, {probeType: 3, click: true})
// 让scrolly滚动对象监听位置
this.foodsScroll.on('scroll', (pos) => { // 获取scroll滚动的实时位置
this.scrollY = Math.abs(Math.round(pos.y)) // 本身是个负值,取正值
})
},
// 计算每个类别所有item的高度,并存放到listHeight数组中
_calculateHeight () {
let foodList = this.$refs.foodList
let foodListArr = [].concat.apply([], foodList)
let height = 0
this.listHeight.push(height)
foodListArr.forEach((item) => {
height += item.clientHeight
this.listHeight.push(height)
})
}
}
计算左侧菜单栏的index值
computed: {
currentIndex () {
for (let i = 0; i < this.listHeight.length; i++) { // 遍历listHeight数组
let height1 = this.listHeight[i] //获取第i个元素的高度
let height2 = this.listHeight[i + 1] //获取第i+1个元素的高度
// 当scroll实时滚动的y向位置不等于height2或者介于height1和height2之间,返回索引值i
if (!height2 || (this.scrollY >= height1 && this.scrollY < height2)) {
return i
}
}
return 0
},