vue實現(xiàn)導航欄下拉菜單
本文實例為大家分享了vue實現(xiàn)導航欄下拉菜單的具體代碼,供大家參考,具體內容如下
先看效果:

下拉菜單鋪滿全屏
<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;
? }
}優(yōu)點:
1、結構層次清楚
2、多個導航需要下拉菜單,且結構相似內容不同,只需要重新渲染數(shù)據(jù)即可。
缺點:
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

優(yōu)點:
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>以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
vue實現(xiàn)el-select 觸底分頁+遠程搜索的示例
有的時候數(shù)據(jù)量比較大,比如幾千甚至上萬條的時候,如果直接賦值,整個頁面的 dom 會被撐爆,本文主要介紹了vue實現(xiàn)el-select 觸底分頁+遠程搜索的示例,具有一定的參考價值,感興趣的可以了解一下2023-12-12
vue router-link 默認a標簽去除下劃線的實現(xiàn)
這篇文章主要介紹了vue router-link 默認a標簽去除下劃線的實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
vue實現(xiàn)tab切換的3種方式及切換保持數(shù)據(jù)狀態(tài)
這篇文章主要給大家介紹了關于vue實現(xiàn)tab切換的3種方式及切換保持數(shù)據(jù)狀態(tài)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-05-05

