1.页面布局展示
2.开始实现
(1)App页面(根页面)
<script setup lang="ts">
import Layout from './components/Layout.vue';
</script>
<template>
<Layout>
// router-view 通过slot放出来,方便后期改造(比如 keep-alive什么的)
<router-view />
</Layout>
</template>
<style lang="less" scoped></style>
(2) layout实现
<script setup lang="ts">
import Aside from './aside/index.vue';
</script>
<template>
<section class="h-full flex">
<Aside />
<div class="flex-1 overflow-hidden">
<slot></slot>
</div>
</section>
</template>
<style lang="less" scoped></style>
(3)Aside 实现(一个展示页面 + 一个 可无限嵌套的menuList组件)
一. Aside主页面实现
<script lang="ts">
// 为了让组件名字展示成Aside(而不是index),网上查了一下 需要安装 unplugin-vue-define-options 才给 setup 语法糖用,想了想这个也可以接受
export default {
name: 'Aside',
};
</script>
<script lang="ts">
export default {
name: 'Aside',
};
</script>
<script setup lang="ts">
import { ref, watchPostEffect } from 'vue';
import { routes } from '../../router/index';
import MenuList from './MenuList.vue';
import { useRoute } from 'vue-router';
const isCollapse = ref(false);
const defaultActive = ref('/');
const route = useRoute();
watchPostEffect(() => {
defaultActive.value = route.path;
});
</script>
<template>
<section class="h-full flexcol">
<el-menu
class="flex-1"
router
:collapse="isCollapse"
active-text-color="#ffd04b"
background-color="#545c64"
:default-active="defaultActive"
text-color="#fff"
>
<MenuList :menus="routes"></MenuList>
</el-menu>
<el-button type="primary" @click="isCollapse = !isCollapse">
<el-icon v-if="!isCollapse"><ArrowRightBold /></el-icon>
<el-icon v-else><ArrowLeftBold /></el-icon>
</el-button>
</section>
</template>
<style lang="less" scoped></style>
二. 嵌套menuList组件实现
<script setup lang="ts">
import { RouteRecordRaw } from 'vue-router';
interface PropsVO {
menus: RouteRecordRaw[] | [];
}
withDefaults(defineProps<PropsVO>(), {
menus: () => [],
});
</script>
<template>
<template v-for="menu in menus">
<!-- 类型为菜单时,使用 el-sub-menu -->
<el-sub-menu
v-if="menu.meta!.isShow && menu.children && menu.children.length"
:key="menu.path + 'submenu'"
:index="menu.path"
>
<template #title>
<el-icon><location /></el-icon>
<span>{{ menu.meta!.name }}</span>
</template>
<!-- 只有菜单有下级,所以放在这个位置 -->
<menu-list :menus="menu.children"></menu-list>
</el-sub-menu>
<!-- 类型为功能时,使用 el-menu-item -->
<template v-else>
<el-menu-item v-if="menu.meta!.isShow" :key="menu.path + 'item'" :index="menu.path">
<el-icon><location /></el-icon>
<template #title>{{ menu.meta!.name }}</template>
</el-menu-item>
</template>
</template>
</template>
附加一个路由吧
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import HomeView from '../views/HomeView.vue';
// meta中isShow 是否展示菜单 meta中name 菜单的名字 meta可以加一个icon,用作前面的小图标
export const routes: Array<RouteRecordRaw> = [
{
path: '/',
meta: {
isShow: false,
},
redirect: {
path: '/home',
},
},
{
path: '/home',
name: 'home',
meta: {
name: '首页',
isShow: true,
},
component: HomeView,
},
{
path: '/about',
name: 'about',
meta: {
name: 'about',
isShow: true,
},
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue'),
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
附上仓库代码 github.com/maqianbo-we… ,有问题,或者宝贵意见的小伙伴欢迎评论,赠人玫瑰,手留余香,如果对您有帮助,希望帮忙点个赞,谢谢!!!