vue和better-scroll实现列表左右联动效果详解
程序员文章站
2024-03-31 10:36:22
一.实现思路
(1)实现上是左右分别一个better-scroll列表
(2)利用计算右侧列表每一个大区块的高度来计算左侧的位置
二.实现
1.实现...
一.实现思路
- (1)实现上是左右分别一个better-scroll列表
- (2)利用计算右侧列表每一个大区块的高度来计算左侧的位置
二.实现
1.实现左右两个better-scroll
(1)dom结构(better-scroll要求,会把最外层dom的第一个子元素作为要滚动的区域)
左边滚动列表dom <div class="menu-wrapper" v-el:menu-wrapper> <ul> <li v-for="item in goods" class="menu-item" :class="{'current':currentindex === $index}" @click="selectmenu($index,$event)"> <span class="text border-1px"> <span v-show="item.type > 0" class="icon" :class="classmap[item.type]"></span>{{item.name}} </span> </li> </ul> </div> 右边滚动列表dom <div class="food-wrapper" v-el:food-wrapper> <ul> <li v-for="item in goods" class="food-list food-list-hook"> <h1 class="title">{{item.name}}</h1> <ul> <li v-for="food in item.foods" class="food-item border-1px"> <div class="icon"> <img width="57" height="57" :src="food.icon"> </div> <div class="content"> <h2 class="name">{{food.name}}</h2> <p class="desc">{{food.description}}</p> <div class="extra"> <span class="count">月售{{food.sellcount}}份</span> <span>好评率{{food.rating}}%</span> <div class="price"> <span class="now">¥{{food.price}}</span> <span class="old" v-show="food.oldprice">¥{{food.oldprice}}</span> </div> </div> </div> </li> </ul> </li> </ul> </div>
在数据请求完成后的$nexttick中初始化better-scroll,就能实现两个列表分别能滚动,至于联动,要后面自己做
_initscroll() { this.menuscroll = new bscroll(this.$els.menuwrapper,{ click:true //允许better-scroll列表上的点击事件 }); this.foodsscroll = new bscroll(this.$els.foodwrapper,{ probetype : 3 //让better-scroll监听scroll事件 }); this.foodsscroll.on('scroll',(pos) => { this.scrolly =math.abs(math.round(pos.y)); }) },
2.实现联动效果
(1)具体的联动实现思路
- 在渲染完成后($nexttick内),初始化better-scroll,并在初始化函数内添加右侧列表的scroll监听事件,并记录scrolly值到,存入vue的data中
- 在渲染完成后($nexttick内),计算右侧列表的每一个大区块的高度,并累加,存入数组listheight
- 因为scrolly值在滚动中总是不断变化的,所以在computed中计算出currentindex,当前滚动区域是哪一个大区块,也就是listheight数组的下标
- 在dom中根据currentindex应用左侧列表被点中的样式
- 在左侧列表某一项被点中的时候,右侧列表滑动到某一个大块区域,
//初始化better-scroll _initscroll() { this.menuscroll = new bscroll(this.$els.menuwrapper,{ click:true }); this.foodsscroll = new bscroll(this.$els.foodwrapper,{ probetype : 3 }); this.foodsscroll.on('scroll',(pos) => { this.scrolly =math.abs(math.round(pos.y)); }) },
_calculateheight() { let foodlist = this.$els.foodwrapper.getelementsbyclassname("food-list-hook"); let height = 0; this.listheight.push(height); for(let i=0;i<foodlist.length;i++) { let item = foodlist[i]; height += item.clientheight; this.listheight.push(height); } }
computed: { currentindex() { 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)){ return i; } } return 0; } },
<div class="menu-wrapper" v-el:menu-wrapper> <ul> <!-- :class="{'current':currentindex === $index}" 就是根据currentindex应用左侧列表被点中的样式 --> <li v-for="item in goods" class="menu-item" :class="{'current':currentindex === $index}" @click="selectmenu($index,$event)"> <span class="text border-1px"> <span v-show="item.type > 0" class="icon" :class="classmap[item.type]"></span>{{item.name}} </span> </li> </ul> </div>
//被点击事件 //dom <div class="menu-wrapper" v-el:menu-wrapper> <ul> <!-- @click="selectmenu($index,$event)" 就是点击事件 --> <li v-for="item in goods" class="menu-item" :class="{'current':currentindex === $index}" @click="selectmenu($index,$event)"> <span class="text border-1px"> <span v-show="item.type > 0" class="icon" :class="classmap[item.type]"></span>{{item.name}} </span> </li> </ul> </div> //js selectmenu(index,event) { if(!event._constructed) { return ; } let foodlist = this.$els.foodwrapper.getelementsbyclassname("food-list-hook"); let el = foodlist[index]; this.foodsscroll.scrolltoelement(el,300); },
以上所述是小编给大家介绍的vue和better-scroll实现列表左右联动效果详解整合,希望对大家有所帮助