JavaScript

超轻量级php框架startmvc

vue和better-scroll实现列表左右联动效果详解

更新时间:2020-08-24 01:30:02 作者:startmvc
一.实现思路(1)实现上是左右分别一个better-scroll列表(2)利用计算右侧列表每一个大区块的高

一.实现思路

  1. (1)实现上是左右分别一个better-scroll列表
  2. (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)具体的联动实现思路

  1. 在渲染完成后($nextTick内),初始化better-scroll,并在初始化函数内添加右侧列表的scroll监听事件,并记录scrollY值到,存入vue的data中
  2. 在渲染完成后($nextTick内),计算右侧列表的每一个大区块的高度,并累加,存入数组listHeight
  3. 因为scrollY值在滚动中总是不断变化的,所以在computed中计算出currentIndex,当前滚动区域是哪一个大区块,也就是listHeight数组的下标
  4. 在dom中根据currentIndex应用左侧列表被点中的样式
  5. 在左侧列表某一项被点中的时候,右侧列表滑动到某一个大块区域,

//初始化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实现列表左右联动效果详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

vue better-scroll列表左右联动 better-scroll实现列表联动