elmentUI多级菜单动态显示

背景:根据后端返回数据生成多级菜单,菜单项可能会有很深的层级,如果直接使用elementUI 去编写会写很深的层级,代码繁杂,一旦后面菜单项有改动又不利于维护

如何做到多级菜单?使用递归组件

elmentUI原本写法:

html 复制代码
<el-menu
      default-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使用函数式组件写法;
html 复制代码
    <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-item
        v-for="child in item.children"
        :key="child.path"
        :item="child"
        :base-path="resolvePath(child.path)"
        class="nest-menu"
      ></sidebar-item>
    </el-submenu>
javascript 复制代码
 // 判断当前菜单是否有子菜单
    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写法:

  1. functional:true定义组件为函数式组件;
  2. props接收父级传入属性;
  3. render函数生成虚拟节点;
javascript 复制代码
<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>
相关推荐
想自律的露西西★6 小时前
用el-scrollbar实现滚动条,拖动滚动条可以滚动,但是通过鼠标滑轮却无效
前端·javascript·css·vue.js·elementui·前端框架·html5
_Legend_King17 小时前
vue3 + elementPlus 日期时间选择器禁用未来及过去时间
javascript·vue.js·elementui
J总裁的小芒果18 小时前
Vue3 el-table 默认选中 传入的数组
前端·javascript·elementui·typescript
ZwaterZ1 天前
vue el-table表格点击某行触发事件&&操作栏点击和row-click冲突问题
前端·vue.js·elementui·c#·vue
码农六六1 天前
vue3封装Element Plus table表格组件
javascript·vue.js·elementui
徐同保1 天前
el-table 多选改成单选
javascript·vue.js·elementui
快乐小土豆~~1 天前
el-input绑定点击回车事件意外触发页面刷新
javascript·vue.js·elementui
大霞上仙1 天前
element ui table 每行不同状态
vue.js·ui·elementui
lv程序媛1 天前
el-table表头前几列固定,后面几列根据接口返回的值不同展示不同
javascript·vue.js·elementui
白臻2 天前
使用element-plus el-table中使用el-image层级冲突table表格会覆盖预览的图片等问题
前端·vue.js·elementui