需求:(思路梳理) 1.初始默认选中主页图标。 2.导航栏鼠标经过图标时,图标为蓝色,且下方显示图标名称。 3.选中子菜单名称时,其所在父级导航改为选中状态,图标为白色。 4.子菜单选中为单选。 6.点击主页图标,恢复到首页。
整个骨架
宽 80px div
for循环导航栏
图标
提示文字
子菜单显示
-for循环提前配好的配置项,方便后期增删改 -图标框需要和下方提示文字分开,因为交互效果不同
知识点1:v-for="(ele,index) in baseMenuCof"
把导航栏分成多个部分,子导航做成一个整体。遍历导航数组,得到并列的三个div。具体样式在这个div内部 子dom层设计,在这一层设置鼠标浮动和鼠标点击事件。
<div v-for="(ele,index) in baseMenuCof"
:key="ele.id"
:data-key="ele.id"
@mouseover="changeMenu(ele.name,index,ele.top)"
@click="backToHome()">
</div>
baseMenuCof:[
{
id:'shouye',
active:'menuActive',
name:'首页',
top:0
},
{
id:'xxxx',
active:'',
name:'xxxx',
top:258-80
},
],
知识点2:border: transparent 4px solid
div内的第一个子元素,图标
<div :class="['menu', ele.active]"><a :class="ele.id+' icon'"></a></div>
.menu设置固定样式 margin和padding,重点是border: transparent 4px solid; 为了鼠标浮动左侧有蓝色提示的时候,图标不会右移。ele.active 用来控制鼠标浮动后的样式,鼠标浮动事件中会给这个ele.active赋值。
知识点3: :class=“ele.id+’ icon’”
图标的颜色替换,用background+class来控制。 用.icon 设置一个整体图片的样式,通过.menu的状态改变来控制更换图片
.menu a.icon{
width: 40px;
height: 40px;
display: inline-block;
background-repeat: no-repeat;
background-size: 50%;
background-color: transparent;
background-position:center;
}
知识点4: “css”: .menu:hover a.icon
可以通过父级的hover、active等交互事件,控制子级的样式。
.menu a.icon.shouye{
background-image: url('../assets/icon/home.png');
}
.menu:hover a.icon.shouye{
background-image: url('../assets/icon/home-hover.png')
}
.menu.menuActive a.icon.shouye{
background-image: url('../assets/icon/home-active.png')
}
知识点5:.menu + span
"+"号是控制.menu标签后的第一个span元素样式,.menu:hover + span{ visibility: visible; } 来通过.menu的鼠标浮动控制span显隐。
完整代码
<template>
<div id="leftMenu">
<img alt="kuandeng logo" src="../assets/logo.png" id="kuandengLogo">
<!-- 一级菜单 -->
<div v-for="(ele,index) in baseMenuCof"
:key="ele.id"
:data-key="ele.id"
@mouseover="changeMenu(ele.name,index,ele.top)"
@click="backToHome()">
<div :class="['menu', ele.active]"><a :class="ele.id+' icon'"></a></div>
<span>{{ele.name}}</span>
</div>
<!-- <span class="menu" @mouseover="changeMenu('首页',$event,0)"> <img src="../assets/icon/home.png" title="首页"></span>
<span :class="{menuActive:menuChild==1,menu:true}" @mouseover="changeMenu('道路等级',$event,1,258-80)" title="道路等级"> <img src="../assets/icon/road-property.png" /></span>
<span :class="{menuActive:menuChild==2,menu:true}" @mouseover="changeMenu('道路类型',$event,2,344-200)" title="道路类型"> <img src="../assets/icon/assets.png" /></span> -->
<!-- 二级菜单 -->
<div id="menuChild" v-show="menuChild>0" >
<!-- <div v-for="ele in baseMenuCof"
:key="'menuChild'+ele.id"
:data-key="'menuChild'+ele.id"
v-show="ele.id!=='shouye'">
<p>{{ele.name}}</p>
<ul v-show="ele.active">
<li v-for="(menu) in ele.id+'Menu'" :key="menu.value" @click="changeLayer(menu.value,$event)">{{menu.name}}</li>
</ul>
</div> -->
<p>{{menuTitle}}</p>
<!-- 整体道路 -->
<ul v-show="menuChild==1">
<li v-for="(menu) in roadMenu" :key="menu.value" @click="changeLayer(menu.value,$event)">{{menu.name}}</li>
</ul>
<!-- 重点资产 -->
<ul v-show="menuChild==2">
<li v-for="(menu) in assetMenu" :key="menu.value" @click="changeLayer(menu.value,$event)">{{menu.name}}</li>
</ul>
</div>
</div>
</template>
<script>
import {roadMenu,assetMenu} from "../common/menu_cof.js"
import {reactive, toRefs} from "vue"
import Bus from "../common/bus.js"
export default {
name: 'leftMenu',
setup() {
const data = reactive({
baseMenuCof:[
{
id:'shouye',
active:'menuActive',
name:'首页',
top:0
},
{
id:'road',
active:'',
name:'道路等级',
top:258-80
},
{
id:'asset',
active:'',
name:'道路类型',
top:344-200
},
],
menuTitle:"", //子菜单标题
menuChild: 0, // !区分当前所在菜单 0为首页 1为整体道路 2为重点资产
roadMenu:roadMenu, //整体道路子菜单
assetMenu:assetMenu, //重点资产子菜单
//切换一级菜单
changeMenu:(title,index,top)=>{
data.menuTitle = title;
data.menuChild = index;
document.getElementById("menuChild").style.top = top + 'px'; // top = (Number(e.clientY)-document.getElementById("menuChild").clientHeight/2
},
//回主页面
backToHome:()=>{
if(data.menuTitle == data.baseMenuCof[0].name){ //只有点首页按钮时触发
//一级菜单切换
data.baseMenuCof.forEach(ele => {
ele.active = ele.name == data.menuTitle ? "menuActive":""
});
//清除图层
data.clearAllLayers();
}
},
changeLayer:(value,e)=>{
//一级菜单切换
data.baseMenuCof.forEach(ele => {
ele.active = ele.name == data.menuTitle ? "menuActive":""
});
//清除
data.clearAllLayers();
//二级菜单高亮 & 图层显示
e.target.className = "menuChildActive";
Bus.emit('setLayoutProperty',{'name':value, 'visibility':'visible'});
// if(e.target.className){ //! 已经高亮并显示图层,当前点击,取消图层
// e.target.className="";
// Bus.emit('setLayoutProperty',{'name':value, 'visibility':'none'});
// }else{ //! 添加此图层
// e.target.className = "menuChildActive";
// Bus.emit('setLayoutProperty',{'name':value, 'visibility':'visible'});
// }
},
clearAllLayers:()=>{
//二级菜单高亮取消let arr = [].slice.call(pagis)
let menuChildActive = [].slice.call(document.getElementsByClassName('menuChildActive'))
if(menuChildActive.length) {
menuChildActive. forEach((ele)=>{
// console.log(ele.removeClass('menuChildActive'))
ele.className=""
})
}
//图层不显示
Bus.emit('clearAll');
}
});
const refData = toRefs(data);
return {
...refData,
};
}
}
</script>
<style scoped>
#leftMenu {
position: fixed;
z-index: 999;
height: 100%;
width: 80px;
background: #141D34;
left: 0px;
}
#kuandengLogo{
height: 40px;
margin: 46px 0;
}
.menu{
width: 72px;
padding: 1px 0;
cursor: pointer;
margin-top: 13px;
display: inline-block;
border: transparent 4px solid;
}
.menu:hover,.menu.menuActive{
background: rgba(114, 126, 157, 0.14);
border-left: #2D50E9 4px solid;
}
.menu a.icon{
width: 40px;
height: 40px;
display: inline-block;
background-repeat: no-repeat;
background-size: 50%;
background-color: transparent;
background-position:center;
}
.menu a.icon.shouye{
background-image: url('../assets/icon/home.png');
}
.menu:hover a.icon.shouye{
background-image: url('../assets/icon/home-hover.png')
}
.menu.menuActive a.icon.shouye{
background-image: url('../assets/icon/home-active.png')
}
.menu a.icon.road{
background-image: url('../assets/icon/road.png');
}
.menu:hover a.icon.road{
background-image: url('../assets/icon/road-hover.png')
}
.menu.menuActive a.icon.road{
background-image: url('../assets/icon/road-active.png')
}
.menu a.icon.asset{
background-image: url('../assets/icon/asset.png');
}
.menu:hover a.icon.asset{
background-image: url('../assets/icon/asset-hover.png')
}
.menu.menuActive a.icon.asset{
background-image: url('../assets/icon/asset-active.png')
}
.menu + span{
color: #BDC7DE;
visibility: hidden;
}
.menu:hover + span{
visibility: visible;
}
#menuChild{
position: fixed;
left: 80px;
background: rgba(23, 31, 54, 0.7);
box-shadow: 1px 0px 0px 0px #000920;
padding: 13px 0;
text-align: left;
padding-inline-start: 0px
}
#menuChild p{
color: rgba(255,255,255,0.4);
text-align: left;
padding-left: 30px;
}
ul{
padding-inline-start: 0px ;
}
#menuChild li{
padding: 10px 41px 10px 40px;
cursor: pointer;
list-style:disc inside;
}
#menuChild li:hover{
color: #AEBCFF;
}
.menuChildActive{
color: #AEBCFF;
background: rgba(114, 126, 157, 0.14);
}
</style>
|