背景:从零搭建一套后台管理系统时,需要递归的将侧边菜单渲染出来。
UI框架:Element-Plus
一、数据类型
export interface Router {
path: String; //路径
name: String; //组件名
meta: Meta; //自定义类型
children: Router[]; //子路由
parentID?: String; //父路由ID
}
export interface Meta {
title: String; //页面名称
}
二、mock数据示例
import { defineStore } from "pinia";
import { Router } from "@/interface/router";
export const userRouter = defineStore("router", {
state: () => ({
// 菜单栏列表
menuTree:[
{
path: "/layout/home",
name: "homes",
meta: { title: "首页" },
children:[]
},
{
path: "/page",
name: "page",
meta: { title: "页面" },
children: [
{
path: "/page/page1",
name: "page1",
meta: { title: "页面1" },
children:[],
parentID:"page"
},
{
path: "/page/page12",
name: "page2",
meta: { title: "页面2" },
children:[],
parentID:"page"
},
],
},
] as Router[],
}),
actions: {},
});
三、组件封装MenuTree.vue
<template>
<template v-for="item in tree">
<el-sub-menu :index="item.name" v-if="item.children && item.children.length > 0">
<template #title>
<el-icon><location /></el-icon>
<span>{{ item.meta.title }}</span>
</template>
<MenuTree :tree="item.children"></MenuTree>
</el-sub-menu>
<el-menu-item :index="item.name" v-else">
<el-icon v-if="!item.parentID"><location /></el-icon>
<span>
{{ item.meta.title }}
</span>
</el-menu-item>
</template>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { Location } from "@element-plus/icons-vue";
import { Router } from "@/interface/router";
const props = defineProps({
tree: {
type: Array<Router>,
required: false,
default: [],
},
});
</script>
<style scoped></style>
四、页面组件引用
<el-menu
class="el-menu-vertical-demo"
:collapse="store.asideCollapse"
background-color="var(--layout-aside-background)"
text-color="#fff"
active-text-color="var(--layout-aside-font-size-color-active)"
>
<MenuTree :tree="routerStore.menuTree"></MenuTree>
</el-menu>