菜单动态显示"/>
elmentUI多级菜单动态显示
背景:根据后端返回数据生成多级菜单,菜单项可能会有很深的层级,如果直接使用elementUI 去编写会写很深的层级,代码繁杂,一旦后面菜单项有改动又不利于维护
如何做到多级菜单?使用递归组件
elmentUI原本写法:
<el-menudefault-active="2"class="el-menu-vertical-demo"@open="handleOpen"@close="handleClose"background-color="#545c64"text-color="#fff"active-text-color="#ffd04b"><el-submenu index="1"><template slot="title"><i class="el-icon-location"></i><span>导航一</span></template><el-submenu index="1-4"><template slot="title">选项4</template><el-menu-item index="1-4-1">选项1</el-menu-item></el-submenu></el-submenu><el-menu-item index="4"><i class="el-icon-setting"></i><span slot="title">导航四</span></el-menu-item></el-menu>
使用递归组件写法:
主要思路:
- 通过数据查找hasOneChild()判断是否有children,有证明有子菜单,有子菜单使用el-submenu封装的组件
- SidebarItem.vue组件内部调用自己的组件;
- 渲染元素组件Item.vue使用函数式组件写法;
<template v-if="hasOneChild(item.children, item) && (!oneChild.children || oneChild.noShowChild)"><app-link v-if="item.redirect != 'noRedirect' && item.meta" :to="resolvePath(item.path)"><el-menu-item :index="resolvePath(item.path)" class="submenu-title-noDropdown"><Item v-if="item.meta" :icon="item.meta.icon" :title="item.meta.title"></Item></el-menu-item></app-link></template><!-- 有子菜单:有多个children --><el-submenu v-else :index="resolvePath(item.path)"><template slot="title" v-if="item.meta"><!-- 没有组件数据要处理可以使用函数式组件进行渲染 --><Item :icon="item.meta.icon" :title="item.meta.title"></Item></template><!-- el-submenu里面还有多级菜单 --><sidebar-itemv-for="child in item.children":key="child.path":item="child":base-path="resolvePath(child.path)"class="nest-menu"></sidebar-item></el-submenu>
// 判断当前菜单是否有子菜单hasOneChild(children = [], item) {// 判断如果菜单是隐藏直接不显示// if(item.hidden) return false;if (children.length === 0) return false;const showChildArr = children.filter(child => {console.log(child);if (child.hidden) return false;else return true;});// 没有找到child说明没有子菜单if (showChildArr.length === 0) {this.oneChild = { ...item, path: item.path, noShowChild: true };return true;}console.log(this.oneChild, "this.oneChild");return false;},
函数式组件Item.vue写法:
- functional:true定义组件为函数式组件;
- props接收父级传入属性;
- render函数生成虚拟节点;
<script>
export default {name: "Item",functional: true,// 组件传入的数据props: {title: {type: String,default: ""},icon: {type: String,default: ""}},// render函数生成虚拟节点render(h, context) {// <i class="iconfont el-icon-location"></i>// <span>{{item.meta.title}}</span>const { title, icon } = context.props; //获取传入的属性const vNode = [];if (icon) {const iconClass = `iconfont ` + icon;vNode.push(<i class={iconClass} style="font-size:18px;"></i>);}if (title) {// JSX语法vNode.push(<span style="margin-left:8px;">{title}</span>);}return vNode;}
};
</script>
更多推荐
elmentUI多级菜单动态显示
发布评论