vue实现导航栏下拉菜单

本文实例为大家分享了vue实现导航栏下拉菜单的具体代码,供大家参考,具体内容如下

先看效果:

下拉菜单铺满全屏

<div class="nav">...</div>
<div class="dropdown-content">...</div>
.nav {
    position: relative;
}
.dropdown-content {
    position: absolute;
    width: 100%;  // 拉满
}

下拉动画

方法一:鼠标移入移出事件

使用的是vue的 transition组件以及鼠标事件@mouseenter@mouseleave

.dropdown-enter-active {
  animation: expand-contract 1s ease;
}
.dropdown-leave-active {
  animation: expand-contract 1s ease reverse;
}
@keyframes expand-contract {
  0% {
    overflow: hidden;
    opacity: 0;
    max-height: 0;
  }
  100% {
    max-height: 300px;  // 大于等于下拉菜单的高度
    opacity: 1;
  }
}

优点:

1、结构层次清楚
2、多个导航需要下拉菜单,且结构相似内容不同,只需要重新渲染数据即可。

缺点:

1、使用了事件处理相对复杂

案例代码

<template>
  <div class="app-container">
    <!-- 导航栏 -->
    <div class="nav" ref="navRef">
      <div class="nav-item" @mouseenter="isShow = false">导航栏1</div>
      <div class="nav-item" @mouseenter="showDropDown('2')">导航栏2</div>
      <div class="nav-item" @mouseenter="showDropDown('3')">导航栏3</div>
      <div class="nav-item" @mouseenter="isShow = false">导航栏4</div>
      <div class="nav-item" @mouseenter="isShow = false">导航栏5</div>
    </div>
    <!-- 下拉菜单 -->
    <transition name="dropdown">
      <div v-show="isShow" class="dropdown-content" @mouseleave="hideDropDown">
        <div class="dropdown-menu">
          <div class="menuItem" v-for="(item, index) in analog" :key="index">
            {{ item }}
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShow: false,
      navTop: 0,
      // 模拟下拉菜单内容
      analog: [],
    };
  },
  mounted() {
    // 导航栏距页面高度 = 元素顶部距页面距离 + 元素本身高度
    this.navTop =
      this.$refs.navRef.getBoundingClientRect().top +
      this.$refs.navRef.offsetHeight;
  },
  methods: {
    showDropDown(val) {
      if (!this.isShow) this.isShow = true;
      if (val === "2") {
        this.analog = ["菜单1", "菜单1", "菜单1", "菜单1", "菜单1"];
      } else {
        this.analog = ["菜单22", "菜单22", "菜单22", "菜单22", "菜单22"];
      }
    },
    hideDropDown(e) {
      // e.pageY:鼠标指针相对页面的偏移量
      if (this.isShow && e.pageY >= this.navTop) this.isShow = false;
    },
  },
};
</script>

<style lang="scss" scoped>
// 下拉菜单收缩展开
@keyframes expand-contract {
  0% {
    opacity: 0;
    height: 0;
    // max-height: 0;
  }
  100% {
    opacity: 1;
    height: 300px;
    // max-height: 300px;  // 大于等于下拉菜单的高度
  }
}
.dropdown-enter-active {
  animation: expand-contract 0.6s;
}
.dropdown-leave-active {
  animation: expand-contract 0.6s reverse;
}

// 内容变化
@keyframes menu {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

// 导航栏
.nav {
  position: relative;
  display: flex;
  width: 100%;
  height: 80px;
  line-height: 80px;
  background-color: #eee;
  border-bottom: 1px solid #ccc;
  .nav-item {
    position: relative;
    margin: 0 20px;
    cursor: pointer;
    transition: all 0.3s linear;
    &::before {
      content: "";
      position: absolute;
      bottom: 0;
      left: 0;
      height: 2px;
      width: 100%;
      background-color: #1678e9;
      transform: scale(0);
      transition: all 0.4s linear;
    }
    &:hover {
      color: #1678e9;
      &::before {
        transform: scale(1);
      }
    }
  }
}
.dropdown-content {
  position: absolute;
  width: 100%; // 拉满
  overflow: hidden;
  .dropdown-menu {
    padding: 10px 8px 15px;
    color: white;
    background-color: rgba($color: #ccc, $alpha: 0.5);
    border-radius: 4px;
    /* animation: menu 0.6s; */
    .menuItem {
      width: 100%;
      white-space: nowrap;
      padding: 10px 16px;
      font-size: 16px;
      color: #000;
      cursor: pointer;
      transition: all 0.3s;
      border-radius: 4px;
      &:hover {
        background-color: #ccc;
      }
    }
  }
}
</style>

方法二:hover

将下拉菜单需要下拉的导航栏下一级下,使用hover 控制元素,nav-item不要设置相对定位,以免定位时下拉菜单宽度不能100%铺满导航栏宽度。

将菜单初始高度设为0

优点:

1、简单明了,不需要事件,js等操作

缺点:

1、每个下拉菜单独立,也就是说切换导航栏,下拉菜单显示隐藏也会动画堆叠
2、每个导航标题都需要单独写下拉菜单,结构层次变多

案例代码

<template>
  <div class="app-container">
    <!-- 导航栏 -->
    <div class="nav">
      <div class="nav-item"><span class="nav-item-title">导航栏1</span></div>
      <div class="nav-item">
        <span class="nav-item-title">导航栏2</span>
        <!-- 下拉菜单 -->
        <div class="dropdown-content">
          <div class="dropdown-menu">
            <div class="menuItem">菜单1</div>
            <div class="menuItem">菜单菜单1</div>
            <div class="menuItem">菜单2</div>
            <div class="menuItem">菜单菜单菜单1</div>
            <div class="menuItem">菜单3</div>
          </div>
        </div>
      </div>
      <div class="nav-item"><span class="nav-item-title">导航栏3</span></div>
      <div class="nav-item">
        <span class="nav-item-title">导航栏4</span>
        <!-- 下拉菜单 -->
        <div class="dropdown-content">
          <div class="dropdown-menu">
            <div class="menuItem">菜单1</div>
            <div class="menuItem">菜单菜单1</div>
            <div class="menuItem">菜单2</div>
            <div class="menuItem">菜单菜单菜单1</div>
            <div class="menuItem">菜单3</div>
          </div>
        </div>
      </div>
      <div class="nav-item"><span class="nav-item-title">导航栏5</span></div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShow: false,
    };
  },
  mounted() {},
  methods: {},
};
</script>

<style lang="scss" scoped>
.nav {
  position: relative;
  display: flex;
  width: 100%;
  height: 80px;
  line-height: 80px;
  background-color: #eee;
  border-bottom: 1px solid #ccc;
  .nav-item {
    // position: relative;
    margin: 0 20px;
    cursor: pointer;
    transition: all 0.3s linear;
    .nav-item-title {
      position: relative;
      display: block;
      height: inherit;
      width: inherit;
      &::before {
        content: "";
        position: absolute;
        bottom: 0;
        left: 0;
        height: 2px;
        width: 100%;
        background-color: #1678e9;
        transform: scale(0);
        transition: all 0.4s linear;
      }
      &:hover {
        color: #1678e9;
        &::before {
          transform: scale(1);
        }
      }
    }
    &:hover .dropdown-content {
      height: 300px;
    }
  }
  // 下拉菜单
  .dropdown-content {
    position: absolute;
    top: 80px; // 为导航栏高度
    left: 0; // 设置为0, 不然会直接定位到父元素下方
    width: 100%;
    height: 0; // 下拉初始高度
    overflow: hidden;
    transition: 0.6s;
    .dropdown-menu {
      padding: 10px 8px 15px;
      color: white;
      background-color: rgba($color: #ccc, $alpha: 0.5);
      border-radius: 4px;
      .menuItem {
        width: 100%;
        height: 42px;
        white-space: nowrap;
        padding: 0 16px;
        font-size: 16px;
        line-height: 42px;
        color: #000;
        cursor: pointer;
        transition: all 0.3s ease-in-out;
        border-radius: 4px;
        &:hover {
          background-color: #ccc;
        }
      }
    }
  }
}
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue实现nav导航栏的方法

    每一个网页项目都少不了导航栏,通过原始的方法基本上都是可以写出来的.但是要写出代码量少,冗余度低的代码就要动脑子思考一下了. 最近写了一个百度地图的项目,要求底部有一个导航栏.具体如下图: 首先,拿到了底部导航栏的所有图标图片,图片都有两种.灰色的代表未选中,选中的用带样色的图片替换. 先看一下,组件中 html结构:通过vue提供的v-for方法,进行遍历显示footNav这个数组.数组里边存放着{title:"银行",url:" ",url1:" &q

  • 详解Vue用自定义指令完成一个下拉菜单(select组件)

    这次分享的是关于Vue自定义指令的使用方法,学习完基础后我们再来实战完成一个下拉列表,废话不多说,直接上干货 基本用法 //全局注册 Vue.directive('my-directive', { // 指令选项 }) // 局部注册 var app = new Vue({ el: '#app' directives: { 'my-directive': { // 指令选项 } }) 相信对Vue比较熟悉的人看完都知道,directive的写法与组件 基本类似,只是方法名由component改为

  • 解决vue动态下拉菜单 有数据未反应的问题

    问题出现在当时后台数据会返回到data中但是没有出现下拉菜单,查询资料 发现 Vue的this理解有误 jsp 下拉菜单 <select name="plantModelParentId" v-model="vueObj.plantModelParentId" @change="selectChange"> <option value=""></option> <option v-fo

  • vue使用ElementUI时导航栏默认展开功能的实现

    本文主要参考: http://element.eleme.io/#/zh-CN/component/menu 在使用elementUI的时候发现,能够展开的导航栏是不能展开的,效果这里先不演示了.可以在上边的网站上看到. 现在有这样的需求,就是说,默认的时候需要展开这些导航,就是一打开界面的时候就能够显示导航里面的菜单内容. 具体操作是这样的: <script src="//unpkg.com/vue/dist/vue.js"></script> <scr

  • vue实现导航栏效果(选中状态刷新不消失)

    Vue导航栏 用Vue写手机端的项目,经常会写底部导航栏,我这里总结一套比较方便实用的底部导航栏方法,并且可以解决浏览器刷新选中状态消失的问题.也可以选择自适应屏幕.看一下效果,底部的图标全是UI给的选中和未选中样式的图片,根据公司要求,你也可能会用fontsize去写.(全部代码黏贴到本文的最后面了) 1.首先把这些小图片放到src/assets路径下面(自动base64编码) 2.在data()里边定义一个选中对应的变量isSelect,和循环遍历的数组,数组下面放图标对应的文字,和选中,未

  • vue实现下拉菜单树

    本文实例为大家分享了vue实现下拉菜单树的具体代码,供大家参考,具体内容如下 效果:使用 Vue-Treeselect 实现 建议通过npm安装vue-treeselect,并使用webpack之类的捆绑器来构建您的应用程序. npm install --save @riophae/vue-treeselect 官网实例 配置属性请查看官网 <!-- Vue SFC --> <template> <div id="app"> <treesele

  • vue实现带过渡效果的下拉菜单功能

    本文实例为大家分享了vue中仿写下拉菜单功能,带有过渡效果(移动端),供大家参考,具体内容如下 效果图 clickOutside.js 点击目标之外的地方,下拉框隐藏 代码如下: export const clickOutside = { bind(el, binding, vnode) { function documentHandler(e) { if (el.contains(e.target)) { return false; } if (binding.expression) { bi

  • Vue实现导航栏菜单

    本文实例为大家分享了Vue实现导航栏菜单的具体代码,供大家参考,具体内容如下 这里是刚学习vue的时候,没有用vue的任何UI组件库写的导航栏菜单. menu.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>导航栏左</title> <link rel="stylesheet" href="css/

  • Vue实现自定义下拉菜单功能

    先看例子,后面有对用到的知识点的总结 效果图: 实现代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>组件练习</title> <link rel="stylesheet" type="text/css" href="component.c

  • vue下拉菜单组件(含搜索)的实现代码

    之前也写过这个小组件,最近遇到select下加搜索的功能,所以稍微完善一下. 效果图: 子组件 dropdown.vue <template> <div class="vue-dropdown default-theme"> <div class="cur-name" @click="isShow =! isShow">{{itemlist.cur.name}}</div> <div clas

随机推荐