在开发vue单页面应用时,再做权限管理的时候,一般菜单栏是根据登录用户后台传来的信息进行渲染的,这时说明数据是动态的,并且有几层菜单的嵌套是不能预先知道的,这时就需要动态的运用组件递归进行渲染
组件递归时要有几个重要的vue特性要知道
- vue实例化时需要定义name,当定义name属性时组件可以调用自身
- 需要通过props传值,拿到需要渲染的菜单数据,这样组件调用自身的时候,可以传值.
- vue的v-if指令和v-for指令在同时使用的时候需要注意一些问题,(这里不做解释,vue官网有说明)
本文只递归出菜单,如果想做到面包屑的联动,自行补充一下就好啦
(这里是后补的,如果再递归出菜单时出现了收缩bug,看我下一篇文章,如果不许要收缩功能这略过)
//这是组件代码
<template>
<div>
//这嵌套了一层template就是为了解决v-for不和v-if一起使用
<template v-for="(item,i) in menuList">
<el-menu-item v-if="!item.children" :index="item.path" :key="item.path" class="el-menu-item-wrap">
<i :class="item.icon?item.icon:''"></i>
<span slot="title">{{item.name}}</span>
</el-menu-item>
<el-submenu v-if="item.children" :index="i + ''" :key="i+44">
<template slot="title">
<i :class="item.icon?item.icon:''"></i>
<span slot="title">{{item.name}}</span>
</template>
<self-Menu :menu-list="item.children"/>
</el-submenu>
</template>
</div>
</template>
<script>
export default {
name: "self-Menu",
//props属性父组件传过来的,并且在模板中递归的时候需要
props:["menuList"]
}
</script>
<style scoped>
.el-menu-item-wrap{
margin: 15px 0 15px 0;
}
</style>
下面是递归的模拟数据
export default{
menuList:[
{
name: "首页",
path: "/home",
icon: "el-icon-s-platform"
},
{
name: "表单页",
icon: "el-icon-s-order",
children:[
{
name: "基础表单",
path: "baseForm"
},
{
name: "分步表单",
path: "flowForm"
},
{
name: "高级表单",
path: "superForm"
}
]
},
{
name: "权限测试页",
path: "1",
icon: "el-icon-s-goods"
},
{
name: "卡片",
path: "22",
icon: "el-icon-s-grid"
},
{
name: "图标",
path: "33",
icon: "el-icon-s-data"
},
{
name: "分级菜单",
icon: "el-icon-location",
children: [
{
name: "菜单1",
path: "44_1"
},
{
name: "菜单2",
path: "44_2"
},
{
name: "菜单3",
path: "44_3"
},
{
name: "菜单4",
// path: "44_4"
children: [
{
name: "三级菜单",
path: "44_4_1"
}
]
},
]
},
{
name: "操作日志",
path: "55",
icon: "el-icon-s-order"
},
{
name: "Blog后台",
path: "66",
icon: "el-icon-s-claim"
},
{
name: "权限管理",
path: "77",
icon: "el-icon-s-order"
},
{
name: "个人中心",
path: "88",
icon: "el-icon-setting"
},
]
}
看效果