Project scenario:
提示:这里简述项目相关背景:
Click the label to jump to the corresponding page, of course, it can be realized with router-link and router-view.
Here we use other methods to simulate the fading in and out of the side navigation bar after clicking
solution:
1. Encapsulate a custom sidebar
In this case, the menus are all first-level directories, so only ul/li
a custom simple list is used here. (If you have other needs, you are willing to use el-menu and write it yourself)
1. Create the component SelfMenu.vue
<template>
<div>
<ul class="self-page-menu">
<li v-for="(item,i) in pageMenu" :key="item.id" @click="changePage(item.id)" :class="{'self-active-node':activeNode==i}">{
{
item.name}}<i class="el-icon-caret-right self-icon"></i></li>
</ul>
</div>
</template>
<script>
export default {
props:{
pageMenu:{
type:Array,
default:()=>[]
}
},
data(){
return {
activeNode:0
}
},
methods:{
changePage(i){
this.activeNode = i;
this.$emit("switchPageMenu",this.activeNode)
}
}
}
</script>
<style lang="scss" scoped>
.self-page-menu{
list-style:none;
padding:0;
margin:0;
li{
cursor:pointer;
color:#666;
font-size:16px;
height:50px;
padding:17px 40px 14px;
vertical-align:text-top;
.self-icon{
float:right;
}
}
.self-active-node{
color:#1355FD;
background-color:#E9EDFD;
}
}
</style>
2. The subpage fades in and out and the sidebar changes with the height of the subpage
Take A and B as two subpages (assuming that page A has less content, which is less than the page scrolling threshold ; B has more content, which is greater than the scrolling threshold ), the total page is index.vue
1, A, B subpage
A page
<template>
<div>这是A页面</div>
</template>
<script>
export default {
}
</script>
Page B
<template>
<div>这是B页面<h1>内容</h1>(。。。省略300行)</div>
</template>
<script>
export default {
}
</script>
2、index.view
<template>
<div style="height:100%">
<div class="main-area" ref="pageWrap">
<div class="bg p-left">
<self-menu @switchPageMenu="switchMenu" :page-menu="pageMenu"></self-menu>
</div>
<div class="p-right" ref="pageHeight">
<template v-if="recentPage==0">
<transition name="fade-transform" mode="out-in">
<div :key="0" class="back right-item"><page-a></page-a></div>
</transition>
</template>
<template v-if="recentPage==1">
<transition name="fade-transform" mode="out-in">
<div :key="1" class="back right-item"><page-b></page-b></div>
</transition>
</template>
</div>
</div>
</div>
</template>
<script>
import SelfMenu from "./components/SelfMenu.vue";
import pageA from "./A.vue";
import pageB from "./B.vue";
export default {
components:{
pageA,pageB},
data:{
return {
recentPage:0,
minPageHeight:0,//高度记录
pageMenu:[{
name:'A页面',id:0},{
name:'B页面',id:1}]
}
},
mounted(){
this.getHeight();//此处监听被子页面称起父元素的高度,来决定菜单高度
window.onresize = () => {
this.minPageHeight = this.$refs.pageWrap.clientHeight;
this.setTimeOut(() => {
this.getHeight(), 500})
}
},
methods:{
switchMenu(data){
this.recentPage = data;
this.getHeight();
},
getHeight(){
//实现侧边栏随子页面高度变化效果
//由于父元素min-height属性无法继承高度,所以需手动给右测父元素添加height属性
if(!this.recentPage){
//这里判断高度小于滚动临界值的所有页面,例如A页面
this.$refs.pageHeight.style.height = this.minPageHeight + 'px';
} else {
//这里判断高度大于滚动临界值的所有页面,例如B页面
this.$refs.pageHegith.style.height = 'auto';
}
}
}
}
</script>
<style lang="scss" scoped>
//过渡效果
.fade-transform-leave-active,
.fade-transform-enter-active {
transition: all .5s;
}
.fade-transform-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transform-leave-to {
opacity: 0;
transform: translateX(30px);
}
//板块背景
.back{
background-color:#fff;
border-radius:10px;
}
.main-area{
//margin间距包括顶栏共123px,所以保证子页面高度不够情况时,最小高度为滚动临界值
min-height:calc(100% - 123px);
box-sizing:border-box;
position:relative;
.p-left{
position:absolute;
min-height:100%;
width:280px;
padding-top:40px;
}
.p-right{
min-height:100%;//限制右侧最小高度
width:calc(100% - 290px);//与左边菜单栏相隔10px
margin-left:290px;
.right-item{
height:auto;//不限制嵌套子页面高度
min-height:100%;
padding:23px 30px 39px 30px;
}
}
}
</style>