一、原来的导航需要一个一个添加显示
2、定义一个Menu菜单组件,用于显示路由菜单
显示正常
二、这样的话我们可以在App.vue首页页面中添加布局并使用Menu组件,然后在Menu组件中使用elementPlues中的菜单组件,可优化路由菜单
1,在App.vue中添加布局
(1)美化头部添加图标和登录退出下拉框
可以使用在线布局工具
http://jack.jackafan.top/zsd/css/flex/
(2)在使用的Menu.vue组件中美化路由
在菜单组件中使用路由,在点击时中间内容区域显示相应的内容
但是这样还有一个缺点,菜单就在这里自定义写死了,不能根据路由自动加载
在路由中定义一个meta数组用于存储Menu组件中要用到的值
打印下router变量发现router里面的routes存放的就是我们的路由
打印下router发现存放的是当前显示内容对应的导航栏中的路由,rouer中的path就是当前页面的路径
设置默认激活菜单的当前页面
循环中使用的图标是一个组件
在这里之前已经注册了所有的图标
使用这种方式用变量进行组件注册
在组件菜单中使用折叠框
问题:
代码:
Menu.vue菜单组件
<template>
<div class="optionIconWapper">
<component :is="optionIcon" class="optionIcon" @click = "change"></component>
</div>
<el-menu
active-text-color="#ffd04b"
background-color="#545c64"
class="el-menu-vertical-demo"
default-active="$route.path"
text-color="#fff"
:router="true"
:collapse="isCollapse"
>
<template v-for="item1 in $router.options.routes" :key="item1.path">
<el-sub-menu :index="item1.path" v-if="item1.children !=undefined && item1.meta?.isShow !=false">
<template #title>
<component :is="item1.meta?.icon" class="icon"></component>
<span>{{item1.meta?.title}}</span>
</template>
<template v-for="item2 in item1.children" :key="item2.path">
<el-menu-item :index="item2.path" v-if="item2.meta?.isShow != false">
<component :is="item2.meta?.icon" class="icon"></component>
{{item2.meta?.title}}
</el-menu-item>
</template>
</el-sub-menu>
<el-menu-item :index="item1.path" v-if="item1.children ==undefined && item1.meta?.isShow !=false">
<component :is="item1.meta?.icon" class="icon"></component>
<span>{{item1.meta?.title}}</span>
</el-menu-item>
</template>
</el-menu>
</template>
<script setup lang="ts">
import{ref} from 'vue';
const optionIcon = ref("Fold")
const isCollapse = ref(false)
const change =()=>{
optionIcon.value=optionIcon.value == "Fold" ? "Expand":"Fold"
isCollapse.value=!isCollapse.value
}
</script>
<style scoped>
.icon {
height: 18px;
width: 18px;
margin-right: 5px;
}
.el-menu {
border-right: 0px;
}
.optionIcon {
height: 18px;
width: 18px;
color: #fff;
cursor: pointer;
text-align: center;
}
.optionIconWapper {
height: 25px;
text-align: center;
}
</style>
router.index路由
import { title } from "process";
import { createRouter, createWebHashHistory,createWebHistory} from "vue-router";
const routes = [
{
path:'/product',
meta: {title:'商品管理',icon:"Menu"},
children:[
{
path: '/product/add',
component: () => import("@/views/product/Add.vue"),
meta: {title:'商品添加',icon:"CirclePlus"}
},
{
path: '/product/list',
component: () => import("@/views/product/List.vue"),
meta: {title:'商品列表',icon:"ScaleToOriginal"}
},
{
path: '/product/edit',
component: () => import("@/views/product/Edit.vue"),
meta: {title:'商品编辑',icon:"Operation",isShow:false}
},
]
},
{
path:'/login',
component: () => import("@/views/login.vue") ,
meta: {title:'首页',icon:"location"}
},
//接着写第三个path....
]
const router = createRouter({
// history: createWebHashHistory('/'),
history: createWebHistory(),
routes
})
export default router
App.vue首页
<template>
<div class="common-layout">
<el-container>
<el-header>
<div><img src="/logg.jpg" class="logo" /></div>
<div>
<el-icon>
<User />
</el-icon>
<el-dropdown>
<span class="el-dropdown-link">
李四
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item divided>注销</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</el-header>
<el-container>
<el-aside width="200px">
<Menu></Menu>
</el-aside>
<el-main>
<RouterView></RouterView>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script setup lang="ts">
import Menu from '@/components/Menu.vue';
</script>
<style>
.logo {
height: 25px;
}
.el-header {
background-color: #004a70;
display: flex;
justify-content: space-between;
align-items: center;
color: #ffffff;
}
.el-aside {
background-color: #004a70;
height: calc(100vh - 70px);
}
</style>