Vue --- 菜单导航栏

移动端的菜单导航栏(展示式)一般有三种:
1.限量展示,末尾加‘更多’图标(杰出代表:支付宝)
         适用于菜单项特别多,且能再次分类的。简化页面,点击‘更多’跳转菜单页,显示更清晰。(个人见解哈)

在这里插入图片描述
2.轮播式展示(不自动轮播)(杰出代表:美团、饿了么)
         适用于最后一页菜单项数量大于等于单页满额数量一半的情况,不然显示出来不够‘友善’。(个人见解哈)

在这里插入图片描述
3.左右滑动展示(杰出代表:淘宝)
         适用于最后一页菜单项数量小于等于甚至大于单页满额数量一半的情况。这种展示方式,我个人认为最完美了,除非说菜单项超级多。(个人见解哈)

在这里插入图片描述



由于个人偏好第三种展示方式,所以我们今天来说一下第三种菜单导航栏展示方式的实现。


Step1: 基本样式实现
   作为一个前端人猿,这并不是个问题吧。
—我们可以暂时不考虑下方的分页条—

<!-- 仿淘宝首页中的的菜单分类导航 -->
  <div class="pages-box classify">
    <div class="classify-box" ref="menuList" @scroll="scrollEvent">
      <div
        class="classify-items"
        v-for="(item, index) in classifyList"
        :key="index"
      >
        <div class="item" v-for="(i, ind) in item" :key="ind">
          <div class="pic">
            <img :src="i.imageUrl" alt="" />
          </div>
          {{ i.title }}
        </div>
      </div>
    </div>
  </div>
.classify{
  margin: 20px 5vw;
  padding: 10px 0px;
  /* border: 1px solid crimson; */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
/****** 分类导航******/
.classify-box {
  width: 90vw;
  /* height: 200px; */
  padding: 20px 0px;
  /* margin: 20px 5vw; */
  box-sizing: border-box;
  display: flex;
  flex-direction: row;
  /* align-items: center; */
  overflow-x: scroll;
  white-space: nowrap; /*不换行*/
}
.classify-box::-webkit-scrollbar{
  display: none;
}
.classify-items {
  min-width: 20%;
  /* height: 100%; */
  display: flex;
  flex-direction: column;
  align-items: center;
  /* justify-content: center; */
}
.item {
  /* width: 80px; */
  /* height: 50%; */
  margin: 5px 0px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.pic {
  width: 100%;
  height: 0px;
  padding-bottom: 100%;
  position: relative;
  display: flex;
}
.pic img {
  width: 100%;
  height: 100%;
  position: absolute;
}


Step2: 处理数据

	// 一般我的获取到的数据这样的:
	classifyList: [
        {
          id: 1,
          imageUrl: require('../../assets/images/drinks-icon.png'),
          title: '饮料',
          url: ''
        },
        {
          id: 2,
          imageUrl: require('../../assets/images/entertainment-icon.png'),
          title: '娱乐',
          url: ''
        },
        {
          id: 3,
          imageUrl: require('../../assets/images/fruit-icon.png'),
          title: '水果',
          url: ''
        },
        {
          id: 4,
          imageUrl: require('../../assets/images/hospital-icon.png'),
          title: '医院',
          url: ''
        },
        {
          id: 5,
          imageUrl: require('../../assets/images/hotels-icon.png'),
          title: '住宿',
          url: ''
        },
        {
          id: 6,
          imageUrl: require('../../assets/images/seafood-icon.png'),
          title: '海鲜',
          url: ''
        },
        {
          id: 7,
          imageUrl: require('../../assets/images/snacks-icon.png'),
          title: '零食',
          url: ''
        },
        {
          id: 8,
          imageUrl: require('../../assets/images/surround-icon.png'),
          title: '周边',
          url: ''
        },
        {
          id: 9,
          imageUrl: require('../../assets/images/tour-icon.png'),
          title: '旅游',
          url: ''
        },
        {
          id: 9,
          imageUrl: require('../../assets/images/vegetable-icon.png'),
          title: '蔬菜',
          url: ''
        },
        {
          id: 10,
          imageUrl: require('../../assets/images/vegetable-icon.png'),
          title: '蔬菜',
          url: ''
        }
      ]

但是这样的数据不利于我们布局,所以需要将数据分成2两两一组。

在这里插入图片描述

//  将1维数组转换为numArray维数组
//  arr:需要处理的数组
//  numArray:几个为一组
    classifyListDeal (arr, numArray) {
      let tempArray = []
      for (let i = 0, k = -1; i < arr.length; i += 1) {
        if (i % numArray === 0) {
          k += 1
          tempArray[k] = []
        }
        tempArray[k].push(arr[i])
      }
      this.classifyList = tempArray
      console.log('处理后的classifyArray', this.classifyList)
    },


Step3: 接下来就是来搞下方的分页条了。
              分页条 = 轨道 + 滑块

轨道   给个固定的值(这里直接给了100px)。
滑块   根据 菜单栏的总长度与展示长度的比值 设置滑块长度
          滑块滑动距离就与 滑块长度、菜单长度以及才懂滚动距离有关。

<!-- 分页器 -->
<!--分页器的父级:pages-box classify,兄弟:classify-box -->
    <div class="classify-bar" :style="{'width':((classifyList.length - 5) / classifyList.length *100)*classifyList.length + 'px'}"  v-if="classifyList.length > 5">
      <div class="bar-track">
        <div class="bar-thumb" :style="{'width':(5 / classifyList.length *100) + 'px','margin-left': thumbL + 'px'}"></div>
      </div>
    </div>
// 滚动事件
    scrollEvent (e) {
      let that = this
      let menuList = that.$refs.menuList
      let eleW = (1 - (that.classifyList.length - 5) / that.classifyList.length) *100
      that.thumbL = eleW / (menuList.offsetWidth / menuList.scrollLeft)
    }
/* 分页器 */
.classify-bar{
  width: 100px;
  height: 4px;
}
.classify-bar .bar-track{
  width: 100%;
  height: 100%;
  border-radius: 4px;
  background: darkseagreen;
  overflow: hidden;
}
.classify-bar .bar-thumb{
  height: 100%;
  border-radius: 4px;
  background:darkslategray;
}

实现效果:
在这里插入图片描述

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值