概述
在日常工作中,递归是个人必会的技巧,如果是经常做后台管理系统的,可以经常看到左侧的菜单大差不差基本上都差不多,如果公司扩展不高的话,就手动每次配置一两层就行,但是如果碰到动态配置左侧菜单的情形,这时候必须要递归生成菜单,这样多少层级的菜单都能实现,提高了扩展性,这里主要介绍vue中递归组件的使用。
效果
gif演示,请稍等会儿
实现
前置知识
需要了解vue的递归组件,可以自行前往官网查看具体的解释,说白了就是组件的递归使用,和函数递归的思想是一样的。
代码实现
- 自行初始化项目,我演示用的vue+cli
- 下载组件库,这里element做演示
- 新建Layout.vue组件
<template>
<el-container>
<el-header>Header</el-header>
<el-container>
<el-aside :width="isCollapse ? '64px' : '250px'">
<el-menu
default-active="1"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
popper-append-to-body
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<LayoutMenu :list="permissionTreeData" :collapse="isCollapse"></LayoutMenu>
</el-menu></el-aside
>
<el-main><router-view></router-view></el-main>
</el-container>
</el-container>
</template>
<script>
import { permissionTreeData } from "@/router/permissionTreeData";
import LayoutMenu from "./LayoutMenu.vue";
export default {
components: { LayoutMenu },
data() {
return {
isCollapse: false,
permissionTreeData,
};
},
methods: {
toggleMenuShowStatus() {
this.isCollapse = !this.isCollapse;
},
},
};
</script>
<style>
.el-container {
height: 100vh;
width: 100%;
}
.el-header {
background-color: #000;
color: #fff;
}
.el-aside {
height: 100%;
background-color: #545c64;
}
</style>
- 准备好左侧菜单数据,为树形结构的数组
export const permissionTreeData = [
{
name: "design",
label: "设计管理",
id: "1",
children: [
{
name: "design-detail",
label: "设计管理详情",
id: "1-1",
},
],
},
{
name: "I118Test",
label: "国际化测试",
id: "211",
},
{
name: "plantForm",
label: "平台表单管理",
id: "3",
children: [
{
name: "plantForm-list",
label: "平台管理列表",
id: "3-1",
},
],
},
{
name: "user",
label: "用户管理",
id: "211",
},
{
name: "app",
id: "4",
label: "应用管理",
children: [
{
name: "app-detail",
id: "4-1",
label: "应用详情",
children: [
{
name: "app-detail-test",
label: "应用详情测试",
id: "4-2",
},
{
name: "app-preview",
label: "应用详情预览",
id: "4-3",
children: [
{
name: "plantForm-list",
label: "应用详情编辑",
id: "4-3-1",
},
],
},
{
name: "design-detail",
label: "设计器详细信息",
id: "4-4",
},
],
},
{
name: "app-detail",
label: "应用详情",
id: "5-1",
children: [
{
name: "app-detail-test",
label: "应用注册",
id: "5-2",
},
{
name: "I118Test",
label: "应用部署",
id: "5-3",
},
{
name: "design-detail",
label: "应用发布",
id: "5-4",
},
],
},
],
},
];
新建LayutMenu.vue组件
注意:name一定要给,递归组件的核心
<template>
<div>
<template v-for="item in list">
<template v-if="item.children">
<el-submenu :index="item.id">
<template slot="title">
<i class="el-icon-location"></i>
<span :class="collapse ? 'collapse-title' : ''">{{
item.label
}}</span>
</template>
<LayoutMenu :list="item.children"></LayoutMenu>
</el-submenu>
</template>
<template v-else>
<el-menu-item :index="item.id">
<i class="el-icon-location"></i>
<span slot="title" @click="$router.push({ name: item.name })">{{
item.label
}}</span>
</el-menu-item>
</template>
</template>
</div>
</template>
<script>
export default {
//核心,name一定要给,递归组件的核心
name: "LayoutMenu",
props: {
list: {
type: Array,
default: () => [],
},
collapse: {
type: Boolean,
default: false,
},
},
};
</script>
<style>
.collapse-title {
opacity: 0;
}
</style>
总结
上面的菜单数据可以由后端返回,然后前台自行处理成对应权限的菜单数据列表,还可以基于此,实现动态路由权限的功能,总之就是映射,如果对函数递归理解到位的话,其实都还是很好处理的,上面是vue里面的实现,vue3类似的,区别不大。