Vu3+Element-Plus根据路由配置生成菜单导航栏
阅读原文时间:2023年08月12日阅读:1

先看效果,整体界面结构如下

点击左侧菜单栏,右侧切换显示不同页面内容。

Vue3使用路由–南河小站

路由配置如下:

const routes = [
  {
    path: "",
    component: () => import("@/layout/baseView.vue"),
    redirect: "/index",
    children: [
      {
        path: "/index",
        name: "首页",
        icon: "SwitchButton",
        hidden: false,
        component: () => import("@/page/dashboard/dashboard.vue"),
      },
      {
        path: "/content",
        name: "内容",
        icon: "Discount",
        hidden: false,
        component: () => import("@/layout/rightView.vue"),
        children: [
          {
            path: "manage-comment",
            icon: "MessageBox",
            name: "管理评论",
            hidden: false,
            component: () => import("@/page/content/manageComment.vue"),
          },
          {
            path: "manage-image",
            icon: "Odometer",
            name: "管理图片",
            hidden: false,
            component: () => import("@/page/content/manageImage.vue"),
          },
        ],
      },
      {
        path: "/user",
        icon: "UserFilled",
        name: "用户",
        hidden: false,
        component: () => import("@/layout/rightView.vue"),
        children: [
          {
            path: "list",
            icon: "User",
            name: "用户列表",
            hidden: false,
            component: () => import("@/page/user/list.vue"),
          },
          {
            path: "reset-pwd",
            icon: "Unlock",
            name: "重置密码",
            hidden: false,
            component: () => import("@/page/user/resetPwd.vue"),
          },
         // ....
        ],
      },
      {
        path: "/operation",
        icon: "Operation",
        name: "运维",
        hidden: false,
        component: () => import("@/layout/rightView.vue"),
        children: [
          {
            path: "mange-category",
            icon: "Edit",
            hidden: false,
            name: "管理分类",
            component: () => import("@/page/operation/manageCategory.vue"),
          },
          {
            path: "mange-carousel",
            icon: "Crop",
            name: "管理轮播图",
            hidden: false,
            component: () => import("@/page/operation/manageCarousel.vue"),
          },
        ],
      },

    ],
  },
  {
    path: "/login",
    hidden: true,
    component: () => import("@/page/login/login.vue"),
  },
];

说明:

@/layout/baseView.vue是整体页面结构

@/layout/rightView.vue是公共页面用于显示数据内容。

@/page/login/login.vue是登陆页面

右侧数据内容视图是动态的,其它整个页面结构是固定的,因此提取baseView.vue作为页面基本结构。

登录界面是另一个页面整体,因此login.vue和基本结构页面baseView.vue都在App.vue页面中通过路由进行切换,因此App.vue中添加router-view进行动态路由渲染。

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

左侧菜单导航,菜单是根据路由进行动态渲染的,所以将路由生成菜单抽取为独立组组件leftMenuBar.vue。在mounted()中获取路由配置

export default {
  data() {
    return {
      menuList: [],
    };
  },
  mounted() {
    let routes = router.options.routes;
    this.menuList = routes[0].children;
    console.log(this.menuList);
  },
};

️Vue3通过router.options.routes 获取配置的路由

在右侧数据视图页面rightView.vue添加router-view标签

<template>
  <div class="right-view">
    <div class="header"></div>
    <div class="content">
      <router-view></router-view>
    </div>
  </div>
</template>

导入Element-plus

遍历路由通过element-plusMenu组件生成菜单导航,完整的代码如下:

<template>
  <div>
    <el-menu
      default-active="0"
      :unique-opened="true"
      class="el-menu-vertical-demo"
    >
      <template v-for="(item, index) in menuList" :key="index">
        <router-link :to="item.path" v-if="!item.children" :key="index">
          <el-menu-item :index="index + ''">
            <el-icon><component :is="item.icon"></component></el-icon>
            <span>{{ item.name }}</span>
          </el-menu-item>
        </router-link>

        <el-sub-menu :index="index + ''" v-else>
          <template #title>
            <el-icon><component :is="item.icon"></component></el-icon>
            <span>{{ item.name }}</span>
          </template>
          <router-link
            :to="item.path + '/' + sub.path"
            v-for="(sub, subIndex) in item.children"
            :key="subIndex"
          >
            <el-menu-item :index="index + '-' + subIndex">
              <el-icon><component :is="sub.icon"></component></el-icon>
              <span>{{ sub.name }}</span>
            </el-menu-item>
          </router-link>
        </el-sub-menu>
      </template>
    </el-menu>
  </div>
</template>

由于element-plus使用svg 图标,复制的代码是<el-icon><Search /></el-icon>这样的,因此在遍历路由时,就不能通过<i :calss = "xxxx"></i>设置了,要通过<el-icon><component :is="xxxx"></component></el-icon>来设置,:is绑定的是icon的名称

    <el-icon><component :is="item.icon"></component></el-icon>

️这个地方element不同,element使用的是font-class的图标,可用 直接绑定