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

一.实现思路

(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);
      },
  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Vue是一种用于构建用户界面的渐进式JavaScript框架,它可以帮助开发者更高效地构建单面应用程序。而vue-better-scroll是基于Vue的一款优秀的滚动插件,它能够实现更流畅的滚动效果,并且支持上下左右的滚动和联动效果。 如果需要实现左右侧菜单的联动效果,我们可以通过使用vue-better-scrollscrollToElement方法来实现。首先,我们需要在Vue中引入vue-better-scroll插件并进行配置。 在Vue实例的data中,我们可以定义左右两个菜单的数据,例如leftMenu和rightMenu,并在created生命周期中初始化数据。然后,在mounted生命周期中,我们可以通过refs属性获取到两个菜单容器的DOM元素。 接下来,我们需要监听左边菜单的点击事件,当点击左边菜单的某个选项时,我们可以通过调用vue-better-scrollscrollToElement方法,将右边菜单滚动到对应的位置。通过传递目标元素的选择器或具体的DOM元素,我们可以实现左右菜单的联动效果。 具体实现时,我们可以在左边菜单的点击事件中,使用this.$refs来访问右边菜单容器,并调用scrollToElement方法,将目标元素滚动到可视区域。通过传递选择器或具体DOM元素作为参数,我们可以精确控制滚动的位置。 同时,为了视觉上更好的效果,我们还可以给目标元素添加样式,如高亮当前选中项,以提升用户体验。 最后,通过一系列的事件处理和样式设置,我们就可以实现左右侧菜单的联动demo了。 以上就是使用Vuevue-better-scroll实现左右侧菜单联动demo的大致思路和步骤。通过合理运用这两个工具,我们可以轻松地实现出一个流畅、友好的用户界面效果

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值