文章目录
- 效果展示
- template代码
- script代码
- 样式代码
效果展示
template代码
<template>
<el-container class="home">
<el-aside class="flex" :style="{ width: asideDisplay ? '70px' : '290px' }">
<div class="aside-left">
<div class="aside-logo">
<img src="./logo.png" class="aside-logo-img" />
</div>
<div class="aside-list">
<div class="aside-list-item" :class="{ active: item.path === asideActive }"
v-for="(item, index) in routesList" :key="index" @click="handleRoutes(item)">{{ item.meta.title }}
</div>
</div>
</div>
<div class="aside-right" :style="{ display: asideDisplay ? 'none' : 'block' }">
<div class="aside-right-title">Admin.NET</div>
<div class="aside-right-list">
<div class="aside-right-list-item" :class="{ active: item.path === currentRoute.children.path }"
v-for="(item, index) in routesListItem.children" :key="index" @click="handleRoutesItem(item)">{{
item.meta.title }}</div>
</div>
</div>
</el-aside>
<el-container class="flex1">
<el-header class="">
<div class="header-navbars-container">
<el-icon v-if="asideDisplay" @click="asideDisplay = !asideDisplay">
<Expand />
</el-icon>
<el-icon v-if="!asideDisplay" @click="asideDisplay = !asideDisplay">
<Fold />
</el-icon>
<el-breadcrumb separator="/">
<el-breadcrumb-item>{{ currentRoute.meta.title }}</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: currentRoute.children.path }">
{{ currentRoute.children.meta.title }}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="header-navbars-tagsview">
<span class="header-navbars-tagsview-span">
<span class="header-navbars-tagsview-item" v-for="(item, index) in currentList" :key="index"
@click="handleRoutes(item)" :class="{ 'active': item.path === currentRoute.children.path }">
{{ item.meta.title }}
<!-- {{currentList}} -->
<el-icon>
<Close />
</el-icon>
</span>
</span>
</div>
</el-header>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
script代码
<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue';
import type { FormInstance, FormRules } from 'element-plus';
import { Expand, Fold, Close } from '@element-plus/icons-vue';
import { useRouter } from 'vue-router';
// 页面加载时
onMounted(() => {
getAllRoutes();
firstEnter();
});
const router = useRouter();// 当前页面的路由对象
const routesList = reactive(new Array<any>());
const asideActive = ref('');
const asideDisplay = ref(true);
const routesListItem = reactive({
meta: { title: '' },
children: new Array<any>(),
name: '',
path: '',
});
const currentRoute = reactive({
meta: { title: '' },
children: {
meta: { title: '' },
name: '',
path: '',
},
name: '',
path: '',
});
const currentList = reactive(new Array<any>());
const getAllRoutes = () => {
const routes = router.getRoutes();
console.log(routes); // 这里会输出所有的路由记录
routes.forEach((route: any) => {
if (route.meta.level == 1) {
console.log(route);
routesList.push(route)
}
})
return routes;
};
const firstEnter = () => {
const value = localStorage.getItem('currentList');
const value2 = localStorage.getItem('routesListItem');
const value3 = localStorage.getItem('currentRoute');
// 检查value是否为null
if (value !== null) {
// 如果value不是null,则尝试解析它
try {
const parsedValue = JSON.parse(value);
parsedValue.forEach((item: any) => {
const valFind = currentList.find((val: any) => {
if (val.name == item.name) {
return val
}
})
if (!valFind) {
currentList.push(item)
}
});
} catch (error) {
// 如果解析过程中发生错误,比如value不是一个有效的JSON字符串,则处理错误
console.error('Error parsing JSON:', error);
currentList.push({
name: router.currentRoute.value.name,
path: router.currentRoute.value.path,
meta: {
title: router.currentRoute.value.meta.title
}
})
}
} else {
// 如果value是null,打印null或者做其他处理
console.log(null, 'currentList is null or not set');
currentList.push({
name: router.currentRoute.value.name,
path: router.currentRoute.value.path,
meta: {
title: router.currentRoute.value.meta.title
}
})
}
// 检查value是否为null
if (value2 !== null) {
// 如果value不是null,则尝试解析它
try {
const parsedValue = JSON.parse(value2);
routesListItem.children = parsedValue.children
routesListItem.name = parsedValue.name
routesListItem.path = parsedValue.path
routesListItem.meta = parsedValue.meta
} catch (error) {
// 如果解析过程中发生错误,比如value不是一个有效的JSON字符串,则处理错误
console.error('Error parsing JSON:', error);
}
} else {
// 如果value是null,打印null或者做其他处理
const parsedValue = router.currentRoute.value.matched[1]
routesList.forEach(item => {
if (parsedValue.path.indexOf(item.name) !== -1) {
routesListItem.children = item.children
routesListItem.name = item.name
routesListItem.path = item.path
routesListItem.meta = item.meta
}
})
console.log(routesListItem, 'routesList');
}
if (value3 !== null) {
// 如果value不是null,则尝试解析它
try {
const parsedValue = JSON.parse(value3);
currentRoute.children = parsedValue.children
currentRoute.name = parsedValue.name
currentRoute.path = parsedValue.path
currentRoute.meta = parsedValue.meta
asideActive.value = parsedValue.path
} catch (error) {
// 如果解析过程中发生错误,比如value不是一个有效的JSON字符串,则处理错误
console.error('Error parsing JSON:', error);
}
} else {
// 如果value是null,打印null或者做其他处理
const parsedValue = router.currentRoute.value.matched[2]
routesListItem.children.forEach(item => {
if (parsedValue.path.indexOf(item.path) != -1) {
console.log();
console.log(item, 'item');
currentRoute.children = item
currentRoute.name = routesListItem.name
currentRoute.path = routesListItem.path
currentRoute.meta = routesListItem.meta
asideActive.value = routesListItem.path
}
})
console.log(asideActive, 'currentRoute is null or not set');
}
};
const handleRoutes = (item: any) => {
if (item.name == routesListItem.name) {
asideDisplay.value = !asideDisplay.value
} else {
asideDisplay.value = false
console.log(123123);
}
routesListItem.children = item.children
routesListItem.name = item.name
routesListItem.path = item.path
routesListItem.meta = item.meta
asideActive.value = item.path
// console.log(routesListItem.valueOf);
};
const handleRoutesItem = (item: any) => {
router.push(item.path);
currentRoute.name = routesListItem.name
currentRoute.path = routesListItem.path
currentRoute.meta = routesListItem.meta
currentRoute.children = item
localStorage.setItem('currentRoute', JSON.stringify(currentRoute));
localStorage.setItem('routesListItem', JSON.stringify(routesListItem));
const valFind = currentList.find((val: any) => {
if (val.name == item.name) {
return val
}
})
if (!valFind) {
currentList.push(item)
localStorage.setItem('currentList', JSON.stringify(currentList));
}
};
</script>
样式代码
<style lang="scss">
.home {
width: 100vw;
height: 100vh;
}
.el-container {
width: 100%;
height: 100%;
}
.el-aside {
min-width: 70px;
max-width: 290px;
}
.aside-left {
width: 70px;
height: 100%;
background: #2c3a49;
.aside-logo {
height: 50px;
display: flex;
align-items: center;
justify-content: center;
img {
width: 80%;
height: 80%;
}
}
.aside-list-item {
width: calc(100% - 10px);
height: 40px;
text-align: center;
color: #f0f0f0;
font-size: 12px;
background: #de291080;
cursor: pointer;
margin: 5px;
border-radius: 5px;
line-height: 40px;
}
.active {
background: #de2910;
}
}
.aside-right {
width: 220px;
transition: width 0.3s ease;
border-right: 1px solid #e4e7ed;
.aside-right-title {
width: 220px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: rgba(0, 21, 41, 0.02) 0px 1px 4px;
white-space: nowrap;
font-weight: 800;
font-size: 18px;
color: #11559c;
}
.aside-right-list {
.aside-right-list-item {
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.active {
width: calc(100% - 5px);
border-right: 5px solid #de2910;
color: #de2910;
background-color: #de281027;
}
}
}
.el-header {
padding: 0px;
height: 100px;
}
.header-navbars-container {
background-color: #fff;
border-bottom: 1px solid #f1f2f3;
position: relative;
z-index: 1999;
display: flex;
height: 60px;
.el-icon {
width: 60px;
height: 60px;
font-size: 12px;
svg {
height: 2em;
width: 2em;
}
}
.el-breadcrumb {
// display: flex;
font-size: 14px;
line-height: 60px;
.el-breadcrumb__item {
align-items: center;
display: math;
float: none;
}
}
}
.header-navbars-tagsview {
min-height: 40px;
padding-right: 20px;
background-color: #fff;
border-bottom: 1px solid #f1f2f3;
overflow: auto;
.header-navbars-tagsview-span {
white-space: nowrap;
}
.header-navbars-tagsview-item {
// display: inline-block;
line-height: 40px;
margin: 0px 0px 0px 10px;
font-size: 12px;
background-color: #de291080;
padding: 5px 10px;
color: #fff;
border-radius: 5px;
cursor: pointer;
white-space: nowrap;
}
.header-navbars-tagsview-item:hover {
background-color: #de2810d2;
}
.el-icon {
position: relative;
top: 2px;
right: -2px;
}
.active {
background-color: #de2910;
}
}
.el-main {
min-width: 1000px;
}
</style>
您好,我是肥晨。
欢迎关注我获取前端学习资源,日常分享技术变革,生存法则;行业内幕,洞察先机。