# vue+elementui动态生成侧拉导航栏

# 一共两种办法,根据情况而定,首先第一种

首先,拿到菜单树结构数据

 nav: [
        {
          icon: "el-icon-s-platform",
          title: "首页",
          path: "/welcome"
        },
        {
          icon: "el-icon-s-operation",
          title: "test",
          path: "/examAdmin"
        },
        {
          icon: "el-icon-setting",
          title: "admin",
          child: [
            {
              title: "testadmin",
              child: [
                {
                  title: "seeexam",
                  path: "/SeeExam"
                },
                {
                  title: "locat",
                  path: "/ExamAllocat"
                },
                {
                  title: "xxc",
                  child: [
                    {
                      title: "aab",
                      path: "/testPaperList"
                    },
                    {
                      title: "bbc",
                      path: "/ExamAllTestPaper"
                    }
                  ]
                },
                {
                  title: "数据包管理",
                  child: [
                    {
                      title: "数据包导出",
                      path: "/DataPacket"
                    }
                  ]
                }
              ]
            },
            {
              title: "rfhm",
              child: [
                {
                  title: "sdfbvn",
                  path: "/SeepracticalExam"
                },
                {
                  title: "rfbn",
                  path: "/TestPract"
                },
                {
                  title: "ola",
                  child: [
                    {
                      title: "dfjk",
                      path: "/SeeTestAsk"
                    }
                  ]
                }
              ]
            },
            {
              title: "qaxcd",
              child: [
                {
                  title: "fsdgfd",
                  path: "/SeeSynthesizeExam"
                },
                {
                  title: "baax",
                  path: "/TestExamPract"
                },
                {
                  title: "sad",
                  child: [
                    {
                      title: "t",
                      path: "/TestExamDataPacket"
                    }
                  ]
                }
              ]
            },
            {
              title: "s",
              child: [
                {
                  title: "r证",
                  path: "/admissionTicket"
                },
                {
                  title: "u",
                  path: "/ExamCollect"
                }
              ]
            },
            {
              title: "q",
              child: [
                {
                  title: "p",
                  child: [
                    {
                      title: "o",
                      path: "/gradeAccept"
                    }
                  ]
                },
                {
                  title: "n",
                  child: [
                    {
                      title: "m",
                      path: "/practicalGrade"
                    }
                  ]
                },
                {
                  title: "l",
                  child: [
                    {
                      title: "k",
                      path: "/reviewGrade"
                    }
                  ]
                }
              ]
            },
            {
              title: "j",
              child: [
                {
                  title: "i",
                  child: [
                    {
                      title: "h",
                      path: "/SeeTestPlan"
                    },
                    {
                      title: "g",
                      path: "/SetTestSign"
                    }
                  ]
                },
                {
                  title: "f",
                  child: [
                    {
                      title: "e",
                      path: "/SeeTestPlanKP"
                    },
                    {
                      title: "d",
                      path: "/SetTestPlanKP"
                    }
                  ]
                },
                {
                  title: "c",
                  child: [
                    {
                      title: "b",
                      path: "/SeeTestPlanDD"
                    },
                    {
                      title: "a",
                      path: "/SetTestPlanDD"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]

拿到树形结构后进行挂载解析操作

 <el-menu
      :default-active="$route.path"
      class="el-menu-vertical"
      ref="menu"
      router
    >
      <!--动态生成sideItem-->
      <template v-for="(item, parentIndex) in nav">
        <SideNav :item="item" :index="parentIndex"  :key="parentIndex"></SideNav>
      </template>
    </el-menu>

// SideNav是子组件,将数据循环并且传递到子组件中
import SideNav from "./SideNav";
  components: {
    SideNav
  }
# sideNav子组件结构(其中,fragment标签是vue编码但是不渲染,不用div避免导航渲染问题)

fragment 是插件 vue-fragment

npm i -s vue-fragment

然后在main.js里面引入即可

import Fragment from “vue-fragment”;

Vue.use(Fragment.Plugin);

具体使用方法可以搜索该标签用法

<template>
  <fragment>
    <!--没有子导航-->
    <el-menu-item v-if="!item.child" :index="item.path">
      <i v-if="item.icon" :class="item.icon"></i>
      <span slot="title">{{ item.title }}</span>
    </el-menu-item>
    <!--有子导航-->
    <el-submenu v-else :index="String(index + 1)+item.title">
      <template slot="title">
        <!--如果item有icon才添加icon图标-->
        <i v-if="item.icon" :class="item.icon"></i>
        <span slot="title">{{ item.title }}</span>
      </template>
      <!--判断子导航是否存在下一级的子导航,如果没有则渲染自己,如果有则递归组件-->
      <!--如果子导航中没有存在下一级的子导航 则是<el-menu-item> 否则为<el-submenu>-->
      <template v-for="(cItem, cIndex) in item.child" :index="String(index + 1 + '-' + cIndex + 1)">
        <el-menu-item v-if="!cItem.child" :index="cItem.path" :key="cItem.path">{{ cItem.title }}</el-menu-item>
        <el-submenu
          v-else
          :index="String(index + 1 + '-' + cIndex + 1)"
          :key="String(index + 1 + '-' + cIndex + 1)"
        >
          <i v-if="item.icon" :class="cItem.icon"></i>
          <span slot="title">{{ cItem.title }}</span>
          <!--递归自己 遍历子..导航-->
          <template v-for="(item, parentIndex) in cItem.child">
            <SideNav :item="item" :index="parentIndex+1" :key="parentIndex"></SideNav>
          </template>
        </el-submenu>
      </template>
    </el-submenu>
  </fragment>
</template>

<script>
export default {
  name: "SideNav",
  props: {
    item: {
      type: Object,
      required: true
    },
    index: {
      type: Number,
      required: true
    }
  }
};
</script>
<style scoped>
.el-submenu [class^="fa"] {
  vertical-align: middle;
  margin-right: 5px;
  width: 24px;
  text-align: center;
  font-size: 16px;
}
</style>

# 第二种动态生成

首先创建父组件去渲染数据

<template>
  <div>
    <el-menu>
      <navigationitem v-for="(menu,i) in adminMenus" :key="i" :item="menu" />
    </el-menu>
  </div>
</template>
<script>
export default {
  data() {
    return {
      adminMenus: [
        {
          id: 1,
          path: "/admin",
          nameZh: "首页",
          parentId: 0,
          iconCls: null,
          children: null
        },
        {
          id: 2,
          path: "/adminbbb",
          nameZh: "用户管理",
          iconCls: null,
          parentId: 0,
          children: [
            {
              id: 6,
              path: "/bgfbfbgf",
              iconCls: null,
              nameZh: "用户信息",
              parentId: 2,
              children: null
            },
            {
              id: 7,
              path: "/gbfbdb",
              iconCls: null,
              nameZh: "角色配置",
              parentId: 2,
              children: null
            }
          ]
        },
        {
          id: 3,
          path: "/dgbdbdb",
          nameZh: "内容管理",
          iconCls: null,
          parentId: 0,
          children: [
            {
              id: 9,
              path: "/dbfdbdbf",
              nameZh: "就业部类",
              iconCls: null,
              parentId: 3,
              children: null
            },
            {
              id: 10,
              path: "/dfbdbdfbdfb",
              nameZh: "学生类",
              iconCls: null,
              parentId: 3,
              children: [
                {
                  id: 20,
                  path: "/dfbdbdfbd",
                  nameZh: "毕业生信息",
                  iconCls: null,
                  parentId: 10,
                  children: null
                }
              ]
            },
            {
              id: 11,
              path: "/dbfdbszbfdz",
              name: "Enterprise",
              nameZh: "企业类",
              iconCls: null,
              component: "content/enterprise",
              parentId: 3,
              children: null
            }
          ]
        },
        {
          id: 4,
          path: "/dfbhdhdfh",
          name: "System",
          nameZh: "系统管理",
          iconCls: "el-icon-s-tools",
          component: "AdminIndex",
          parentId: 0,
          children: [
            {
              id: 12,
              path: "/dfgdhbdfb",
              name: "Run",
              nameZh: "运行情况",
              iconCls: null,
              component: "system/run",
              parentId: 4,
              children: null
            },
            {
              id: 13,
              path: "/dfgbdfhbdfbd",
              name: "Data",
              nameZh: "备份恢复数据库",
              iconCls: null,
              component: "system/data",
              parentId: 4,
              children: null
            },
            {
              id: 14,
              path: "/safgbgfcbcxvbd",
              name: "Log",
              nameZh: "操作日志",
              iconCls: null,
              component: "system/log",
              parentId: 4,
              children: null
            }
          ]
        },
        {
          id: 5,
          path: "/dsgdfhgfdhb",
          name: "Link",
          nameZh: "链接",
          iconCls: null,
          component: "AdminIndex",
          parentId: 0,
          children: null
        }
      ]
    };
  }
};
</script>

组件创建完毕后,在main.js里面将组建注册为全局组件

/**
* 	main.js
*/

import navigationitem from "./components/submen.vue";
Vue.component("navigationitem", navigationitem);

# 创建子组件,去循环父组件传递的数据

<template>
  <div>
    <!--叶子级菜单-->
    <template v-if="item.children==null">
      <el-menu-item :key="item.id" :index="item.path">{{item.nameZh}}</el-menu-item>
    </template>
    <!--父级菜单-->
    <el-submenu v-else :index="item.path" style="text-align: left">
      <span slot="title" style="font-size: 17px;">
        <i :class="item.iconCls"></i>
        {{item.nameZh}}
      </span>
      <template v-for="child in item.children">
        <navigationitem
          v-if="child.children && child.children.length>0"
          :key="child.id"
          :item="child"
        />
        <el-menu-item v-else :key="child.id" :index="child.path">
          <i :class="child.icon"></i>
          {{child.nameZh}}
        </el-menu-item>
      </template>
    </el-submenu>
  </div>
</template>
 
<script>
export default {
  name: "NavigationItem",
  props: {
    item: {
      type: Object,
      required: true
    }
  }
};
</script>

一共两种,欢迎补充,根据情况而定

Logo

前往低代码交流专区

更多推荐