zoukankan      html  css  js  c++  java
  • 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的高度比较问题,同样一段代码,每个项目遇到的问题都是不一样的,我也是参考网上很多的例子,发现一到自己这里就出现了很多问题,每个人遇到的问题都是不一样的,结合自己的问题,想办法解决,这也是成长的一部分。
  • 相关阅读:
    Android sdk + PhoneGap 配置
    一个解析url参数方法
    开始写笔记了~~
    Codevs 3305 水果姐逛水果街Ⅱ 倍增LCA
    Codevs 3304 水果姐逛水果街Ⅰ 线段树
    Cogs 1070. [焦作一中2012] 玻璃球游戏 带权并查集,逆序处理
    Bzoj 1901: Zju2112 Dynamic Rankings 主席树,可持久,树状数组,离散化
    Bzoj 2453: 维护队列 && Bzoj 2120: 数颜色 分块,bitset
    Uoj #131. 【NOI2015】品酒大会 后缀数组,并查集
    Tyvj P1463 智商问题 分块
  • 原文地址:https://www.cnblogs.com/HJ412/p/10755722.html
Copyright © 2011-2022 走看看