Vue使用better-scroll左右菜单联动

说明

  • 最近想做一个vue商城小项目,练习一下vue的语法,刚刚好碰到了需要左右菜单实现联动,因此就接触了 better-scroll。

代码

  • 页面结构以及数据
    //页面结构
    <template> 
      <div id="wrap">
          <div class="goodMenu" ref="goodMenu">
            <ul>
              <li v-for="(item ,index) in goodMenu" :key="index"
               :class="{active: currentIndex === index}"
               @click="selectLeft(index)" ref="lItem">{{ item}}</li>
            </ul>
          </div>
      
          <div class="goodList" ref="goodList">
            <ul>
              <li v-for="(items, index) in goodList" :key="index" ref="rItem">
                <p>{{ items.name}}</p>
            
                <div v-for="(item, key) in items.data" :key="key">
                  {{ item}}
                </div>
              </li>
            </ul>
          </div>
      </div>
    </template> 
        //数据
    <script>

    export default {
      data(){
        return {
          goodMenu: ['菜单1', '菜单2','菜单3', '菜单4', '菜单5', '菜单6', '菜单7', '菜单8'],
          goodList: [
            { name: '菜单1', data: ['1.1', '1.2', '1.3', '1.4', '1.5']},
            { name: '菜单2', data: ['1.1', '1.2', '1.3', '1.4', '1.5', '1.6']},
            { name: '菜单3', data: ['1.1', '1.2', '1.3', '1.4', '1.5']},
            { name: '菜单4', data: ['1.1', '1.2', '1.3', '1.4', '1.5']},
           { name: '菜单5', data: ['1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8']},
            { name: '菜单6', data: ['1.1', '1.2', '1.3', '1.4', '1.5']},
            { name: '菜单7', data: ['1.1', '1.2', '1.3', '1.4']},
            { name: '菜单8', data: ['1.1', '1.2']},
          ],
          scrollY: 0,//获取实时滚动位置
          heightList: []//获取每一个li的高度
        }
      }
    </script>
  • 渲染结果
    • 左边菜单栏(goodMenu)。
    • 右边菜单栏(goodList),每一项有一个标题:name,以及菜单数据: data数组。再结合 v-for指令及相关样式即可完成页面简单布局(不是重点)
    • 其他数据先不必理会,先把页面结构渲染出来,下面会一一讲解。

better-scroll的使用

  • 元素纵轴滚动
    • 元素可以滚动,父元素高度固定overflowhidden,子元素高度超过父元素高度即可滑动,不多解释。
  • 左菜单、右菜单可以在父元素滑动
    • 左菜单栏因为要用到 click事件,默认better-scroll是默认阻止 click事件,设置为true派发一个click事件。
    • 右菜单栏,因为需要滚动,并且需要获取实时滚动距离scrollY,因此设置 probeType设置为3,它有三个值1、2、3。看以查看文档probeType
      //引入better-scroll
      import Bscroll from 'better-scroll'
      export default {
          created(){
              //因为 _scrollInit函数需要操作DOM,因此必须在DOM元素存在文档中才能获取DOM节点
              //因此在 nextTick回调函数里面调用可以是实现此功能
              this.$nextTick(() => { 
                  this._scrollInit()
                  this.getHeight()
              }) 
          },
          methods:{
    
              //初始化 better-scroll
              _scrollInit(){
                  this.menuList = new Bscroll(this.$refs.goodMenu, {
                      click: true
                  })
    
                  this.goodmenu = new Bscroll(this.$refs.goodList, {
                      probeType: 3
                  })
              this.goodmenu.on('scroll', (pos) =>{
                  //获取实时滚动的距离 使用scrollY接收         
                  this.scrollY = Math.abs(Math.round(pos.y))
              })
    
          }
      }
  • 获取右菜单栏每个li的高度
    • 这里获取 li 的高度即为当前li的高度加上之前 li 的高度,第一个元素为 0(必须)
      methods: {
          getHeight(){
              //获取每一个li的高度
              const lis = this.$refs.rItem
              //heightList的第一个元素为0
              let height = 0
              this.heightList.push(height)
              //之后的高度即为当前li的高度加上之前面li的高度和
              lis.forEach(item =>{
              height += item.clientHeight
                 this.heightList.push(height)
              })
             }
      }
  • 右菜单滚动,左菜单同步
    • 这里就是根据右菜单滑动的距离以及每一个每一个 li 的高度的比较返回当前应该显示左菜单 li的索引,让该 li 高亮显示,即:class="{active: currentIndex === index}"
    computed:{
        currentIndex(){
            const index = this.heightList.findIndex((item, index) =>{
                return this.scrollY >= this.heightList[index] && this.scrollY < this.heightList[index + 1]
            })

        return index > 0 ? index : 0
        }
    }
  • 左菜单点击,右菜单同步
    • 把点击的 菜单索引传入,使用scrollToElement滚动到右菜单的目标元素
      selectLeft (index) {
          let rItem = this.$refs.rItem
          let el = rItem[index]
          this.goodmenu.scrollToElement(el, 1000)
      }
  • 问题:有时候 currentIndex 会判断不准确,是滑动距离scrollY 以及右菜单 li的高度比较问题,同样一段代码,每个项目遇到的问题都是不一样的,我也是参考网上很多的例子,发现一到自己这里就出现了很多问题,每个人遇到的问题都是不一样的,结合自己的问题,想办法解决,这也是成长的一部分。

猜你喜欢

转载自www.cnblogs.com/HJ412/p/10755722.html