本文实例为大家分享了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>

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

vue实现导航栏下拉菜单的更多相关文章

  1. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  2. HTML5单选框、复选框、下拉菜单、文本域的实现代码

    这篇文章主要介绍了HTML5单选框、复选框、下拉菜单、文本域的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. Swift下拉菜单动画实现

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  4. 使用视图控制器的切换创建下拉菜单栏

    下拉菜单则是另一种常用的菜单设计。当用户点击菜单按键的是时候主屏幕中下拉显示出菜单选项。如果你不知道下拉菜单是如何实现的话,不需要忧虑。在展示下拉菜单的实现之前,这篇文章已经假设你对自定义视图切换有一定的了解。下拉菜单功能的开始演示在这篇教程中我们会用Swift语言来实现下拉菜单,下面就是最终效果的一个快速展示:工程模版和以往一样,我不希望你从头开始,你可以先去下载起始工程。

  5. Swift 类似美团下拉菜单

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  6. android – 如何在Evernote应用程序中制作这样的下拉菜单?

    单击操作栏中的中间图标时,会出现一个下拉菜单:我如何制作其中一个?

  7. android – WebView / Phonegap更改选择(下拉菜单)样式

    本机选择如下所示:解决方法没有办法实现这一点.您需要做的是构建一个本机插件,当您点击时才会打开一个自定义对话框.您要摆脱的下拉菜单是用于在网络浏览上选择的默认视图,而与Chrome中内置的第二个相反.帮助您开始://获取所有选项并存储在数组中//本机函数获取选项并显示一个对话框确保将您的主题设置为Holo或Holo.Light,您可以选择,并且只要点击select元素,就可以从javascript层调用本机代码.

  8. vue自定义加载指令v-loading占位图指令v-showimg

    这篇文章主要为大家介绍了vue自定义加载指令和v-loading占位图指令v-showimg的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  9. vue使用动画实现滚动表格效果

    这篇文章主要为大家详细介绍了vue使用动画实现滚动表格效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. 关于Vue 监控数组的问题

    这篇文章主要介绍了Vue 监控数组的示例,主要包括Vue 是如何追踪数据发生变化,Vue 如何更新数组以及为什么有些数组的数据变更不能被 Vue 监测到,对vue监控数组知识是面试比较常见的问题,感兴趣的朋友一起看看吧

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部