vue3学习——封装菜单栏
@/Layout/Sidebar/index.vue
<script setup lang="ts">
import Sidebar from './Sidebar.vue' // 在下面的代码里
import { useRoute } from 'vue-router'
import useUserStore from '@/store/modules/user.ts' // state中存放菜单数据
import useLayoutSetting from '@/store/modules/setting.ts' // state存放多页面公用大的数据(fold: 侧边菜单栏是否折叠)
const settingLayout = useLayoutSetting()
const userStore = useUserStore()
const route = useRoute()
</script>
<template>
<div class="sidebar_container">
<el-scrollbar>
<el-menu
router
unique-opened
:default-active="route.path"
:collapse="settingLayout.fold"
active-text-color="#fff"
background-color="#001529"
class="el-menu-vertical-demo"
text-color="#959ea7"
>
<Sidebar
v-for="(item, i) in userStore.menuList"
:key="i"
:menu="item"
/>
</el-menu>
</el-scrollbar>
</div>
</template>
<style lang="scss" scoped>
.sidebar_container {
transition: all 0.5s;
.el-scrollbar {
height: calc(100vh - 60px);
overflow-y: auto;
.el-menu {
border-right: none;
}
}
}
.fold {
width: $sidebar-min-width;
}
</style>
@/Layout/Sidebar/Sidebar.vue
<script setup lang="ts">
defineProps(['menu'])
</script>
<script lang="ts">
export default {
name: 'MenuItem',
}
</script>
<template>
<!-- 没有子路由 -->
<el-menu-item :index="menu.path" v-if="!menu.children && !menu.meta.hidden">
<el-icon v-if="menu.meta">
<component :is="menu.meta.icon"></component>
</el-icon>
<template #title>
<span>{{ menu.meta.title }}</span>
</template>
</el-menu-item>
<!-- 有子路由但只有一个 --home -->
<el-menu-item
:index="menu.children[0].path"
v-if="
menu.children &&
menu.children.length === 1 &&
menu.path === '/' &&
!menu.meta.hidden
"
>
<el-icon>
<component :is="menu.children[0].meta.icon"></component>
</el-icon>
<template #title>
<span>{{ menu.children[0].meta.title }}</span>
</template>
</el-menu-item>
<!-- 有子路由但只有一个 --not home -->
<el-sub-menu
:index="menu.path"
v-if="
menu.children &&
menu.children.length === 1 &&
menu.path !== '/' &&
!menu.meta.hidden
"
>
<el-icon v-if="menu.meta">
<component :is="menu.meta.icon"></component>
</el-icon>
<template #title>
<span>{{ menu.meta.title }}</span>
</template>
<el-menu-item :index="menu.children[0].path">
<template #title>
<el-icon v-if="menu.children[0].meta">
<component :is="menu.children[0].meta.icon"></component>
</el-icon>
<span>{{ menu.children[0].meta.title }}</span>
</template>
</el-menu-item>
</el-sub-menu>
<!-- 有子路由且大于一个 -->
<el-sub-menu
:index="menu.path"
v-if="menu.children && menu.children.length > 1 && !menu.meta.hidden"
>
<template #title>
<el-icon>
<component :is="menu.meta.icon"></component>
</el-icon>
<span>{{ menu.meta.title }}</span>
</template>
<MenuItem v-for="(item, i) in menu.children" :key="i" :menu="item" />
</el-sub-menu>
</template>
<style lang="scss" scoped></style>