目录
效果演示:
一个简单的类手风琴菜单
html:
<template>
<div class="outest-mainpage">
<!-- 左边的导航菜单 -->
<div class="left-nav">
<div class="cover-box">
<div class="status" :style="statusStyle"></div>
<div @click="statusIndex = 0">人资管理</div>
<div class="files" @click="statusIndex = 1">
<div>档案管理</div>
<ul :class="showFileUl ? 'files-ul show-ul' : 'files-ul'">
<li @click="selected(0)" :class="keepStyleLiIndex === 0 ? 'keep-bg-li' : ''">档案登记</li>
<li @click="selected(1)" :class="keepStyleLiIndex === 1 ? 'keep-bg-li' : ''">档案变更</li>
<li @click="selected(2)" :class="keepStyleLiIndex === 2 ? 'keep-bg-li' : ''">档案复核</li>
<li @click="selected(3)" :class="keepStyleLiIndex === 3 ? 'keep-bg-li' : ''">档案查询</li>
<li @click="selected(4)" :class="keepStyleLiIndex === 4 ? 'keep-bg-li' : ''">档案删除与恢复</li>
</ul>
</div>
<div class="sal" @click="statusIndex = 2">
<div>薪酬管理</div>
<ul :class="showSalUl ? 'sal-ul show-ul' : 'sal-ul'">
<li @click="selected(5)" :class="keepStyleLiIndex === 5 ? 'keep-bg-li' : ''">薪酬标准</li>
<li @click="selected(6)" :class="keepStyleLiIndex === 6 ? 'keep-bg-li' : ''">薪酬发放</li>
</ul>
</div>
</div>
</div>
<!-- 中间的主要内容 -->
<div class="center-content">
</div>
</div>
</template>
JS:
<script>
export default{
data(){
return{
statusIndex:0, // 指示轮廓的位置索引
statusStyle:'transform:translate(0,0);', // 大标题的指示轮廓的位置
keepStyleLiIndex:-1, // 保持背景的 li
}
},
methods:{
selected(index){ // 选中了指定的 li 保留其指示背景
this.keepStyleLiIndex = Number.parseInt(index);
}
},
watch:{
statusIndex(newval, oldval){
if(newval === oldval){ // 点击已展开的一级菜单,不变
return;
}
this.keepStyleLiIndex = -1; // 移除原有的 li 指示背景
if(newval === 0){ // 切换指示轮廓 展开和收起对应 ul
this.statusStyle = 'transform:translate(0,0);';
this.showFileUl = false;
this.showSalUl = false;
}else if(newval === 1){
this.statusStyle = 'transform: translate(0,60px)';
this.showFileUl = true;
this.showSalUl = false;
}else if(newval === 2){
this.statusStyle = 'transform: translate(0,120px)';
this.showFileUl = false;
this.showSalUl = true;
}
}
}
}
</script>
CSS:
在这里,一级导航标题独享一个 div ,如果有附属二级导航列表的,就写在一级导航的 div 中、一级导航标题之后。
手风琴效果主要用 ul 的动态高度来实现( transition )。
ul 是二级导航列表,当其依附的一级导航没有被激活时,height :0;
当 ul 所依赖的一级导航被激活时,动态为其添加一个CSS类名,如这里的 .show-ul。该类名经过计算每个 li 的高度以及 li 的个数,算出 ul 的高度,然后设置 height 属性值为 ul 的准确高度。如果不使用具体数值的高度,使用 auto 的话,ul 的展开就没有达到过渡的效果,即展开和收起是在瞬间完成的。
<style lang="scss" scoped>
.outest-mainpage{
width: 100vw;
height: 100vh;
min-width: 1200px;
min-height: 700px;
display: grid;
grid-template-rows: 1fr;
grid-template-columns: 18% 82%;
box-sizing: border-box;
background-image: linear-gradient(to right top, #adc2ff, #a6bdfa, #9fb8f6,
#97b3f1, #90aeed, #97aeee, #9eaeee, #a5aeee, #bbb3f1,
#cfb8f4, #e2bdf5, #f3c3f6);
.left-nav{
box-sizing: border-box;
padding: 50px 0 0 0;
overflow: hidden;
.cover-box{
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
div{
font-size: 1.3rem;
font-weight: 500;
text-align: center;
min-height: 60px;
width: 100%;
line-height: 60px;
}
div:hover{
cursor: pointer;
}
ul{
height: 0;
width: 100%;
overflow: hidden;
transition: all 260ms linear 0s;
text-decoration: none;
font-size: 1rem;
box-sizing: border-box;
padding: 0;
text-align: center;
opacity: 0.8; /** 让文字颜色变淡 */
padding: 0;
margin: 0;
li{
width: 70%;
margin: 0 15%;
box-sizing: border-box;
padding: 0;
line-height: 45px;
height: 45px;
list-style-type: none;
}
li:hover{
border-radius: 20px;
background-color: rgba(#eee,0.2);
}
.keep-bg-li{
border-radius: 20px;
background-color: rgba(#eee,0.2);
}
}
.status{
position: absolute;
width: 90%;
margin-left: 5%;
height: 60px;
left: 0;
border-radius: 30px;
box-shadow: 0px 1px 10px 1px rgba(#eee,0.4);
transition: transform 260ms linear 0s;
}
.files,.sal{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
.show-ul{
height: 225px;
}
}
}
}
.center-content{
box-sizing: border-box;
}
}
</style>