• vue |通过BetterScroll创建动态菜单


    参考:https://juejin.cn/post/6844903655108280328

    效果

    20210126-190337.gif

    BetterScroll

    //安装
    npm install better-scroll --save
    //导入
    import Bscroll from "better-scroll";
    

    滚动原理:需要一个固定高度的父容器,然后在其基础上进行滚动。

    //设scrollH为父容器高度,例:
    this.scrollH= window.innerHeight - 150
    

    整体结构

    相关数据

    data() {
      return {
          foodList:[],//菜品信息
          scrollH:'',//滚轮窗口的高度
          heightList:[],//储存位置
          scrollY:'',//滚动距离
      };
    },
    

    例-foodList数据结构:

    foodList:[
        {name:'菜类',foods:['娃娃菜','大白菜']},
        {name:'肉类',foods:['猪肉','牛肉']},
        {name:'水果',foods:['苹果','西瓜']},
        {name:'甜品',foods:['奶茶','华夫饼']},
    ],
    

    相关DOM

    左侧菜单栏

    <div ref="leftMenu">
      <ul>
        <li
          v-for="(item, index) in foodList"     
          :key="index"
          :class="{ active: currentIndex === index }"
          @click="selectLeft(index)"
        >
          {{ item.name }}
        </li>
      </ul>
    </div>
    
    • ref="leftMenu"获取左侧菜单栏的dom,用于创建滚动窗口
    • @click="selectLeft(index)"点击左侧菜单后触发,用于滑动到指定内容
    • :class="{ active: currentIndex === index }"动态改变样式

    右侧内容栏

    <div ref="rigntMenu" :style="'height:' + scrollH + 'px'" style="overflow: hidden">
      <ul>
        <li v-for="(item, index) in foodList" 
            :key="index" 
            ref="rightItem">
          <span class="rightTitle">{{ item.name }}</span>
          <div
            v-for="(food, key) in item.foods"
            :key="key"
          >
    		{{ food }}
          </div>
        </li>
      </ul>
    </div>
    
    • ref="rigntMenu"获取右侧内容栏的dom,用于创建滚动窗口
    • ref="rightItem"获取某一品类的dom高度
    • :style="'height:' + scrollH + 'px'"动态绑定固定容器的高度

    函数与方法

    创建滚动窗口

    通过new Bscroll(对应dom,{相关配置})创建滚动窗口

    scrollInit() {
        //创建左边菜单栏滚动窗口
        this.leftMenu = new Bscroll(this.$refs.leftMenu, {
            click: true,//允许点击
        });
        
        //创建右边内容栏滚动窗口
        this.rigntMenu = new Bscroll(this.$refs.rigntMenu, {
            probeType: 3, //在 rigntMenu 滚动时触发 scroll 事件
            click: true,
        });
        
        //当右侧滚动时,监听滚动事件获取滚动距离,将滚动距离储存在scrollY中
        //滚动距离:容器顶部与内容顶部的距离
        this.rigntMenu.on("scroll", (pos) => {
            this.scrollY = Math.abs(Math.round(pos.y));
        });
    },
    

    获取右侧项目位置

    getListHeight(){
        const lis=this.$refs.rightItem   //获取每项的DOM
        this.heightList=[]	//储存每项的顶部位置
        let height=0  
        this.heightList.push(height)  //第一项的顶部垂直位置为0
        lis.map(item=>{
            height+=item.clientHeight //第二项顶部位置=第一项顶部位置+第二项的内容高度,以此类推
            this.heightList.push(height)
        })
    },
    

    右侧联动左侧

    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;
        },
    },
    

    左侧联动右侧

    selectLeft(index) {
      let rightItem = this.$refs.rightItem; 
      let el = rightItem[index]; //根据索引获取对应dom
      this.rigntMenu.scrollToElement(el, 1000); //将右侧滚动窗口滚动至对应dom
    },
    

    初始化

    mounted() {
       this.scrollH= window.innerHeight - 150
        this.$nextTick(() => {
            this.scrollInit()
            this.getListHeight()
        })
    }
    

    如果是动态数据,下面的内容可以写在获取数据的函数内部的结尾。

    this.$nextTick(() => {
        this.scrollInit()
        this.getListHeight()
    })
    

    完整demo源码:https://github.com/sanhuamao1/menu-card

  • 相关阅读:
    11G-使用跨平台增量备份减少可移动表空间的停机时间 XTTS (Doc ID 1389592.1)
    如何在asm上定位数据块
    log file switch (checkpoint incomplete)
    踩坑记录(git)-误提交target文件夹删除办法
    踩坑记录(java)-双层增强for调用remove(obj)报错 java.util.ConcurrentModificationException(并发修改异常)
    Zookeeper服务端的创建及简单的客户端创建节点
    SpringAOP(注解方式实现面向切面编程)之常用Before、After、Around
    EasyExcel示例(阿里巴巴)基于Maven
    Redis简单命令(部分示例代码)
    sqlserver日志处理不当而造成的隐患
  • 原文地址:https://www.cnblogs.com/sanhuamao/p/14332106.html
Copyright © 2020-2023  润新知