vue的路由和多级菜单的联动及布局,结合element组件的el-menu的实现.(后台管理系统的基础路由,菜单及页面)

1.话不多说,先上github整体demo代码链接: git整体demo代码

2.效果图: 

效果图

3.说明:此demo并未做路由权限控制,只是vue-router结合element组件库的Layout 布局和NavMenu 导航菜单实现基础后台系统的单级和多级菜单的联动.

4.主要代码文件说明:

5.主要文件代码展示(重点部分均有注释):

1. 路由(router-index.js):

import Vue from "vue";
import VueRouter from "vue-router";
import layOut from '../views/layOut/layOut.vue';     //一二级菜单容器
import thirdLay from '../views/layOut/thirdLay.vue';  //三级菜单容器

Vue.use(VueRouter);


/**
 * hidden:   控制(判断)该路由菜单的显隐(需要不显示的路由配置该项为true即可)
 * meta.title:   菜单名称
 * meta.icon:    菜单图标
 * path:   路由路径(最后一层不需加/)
 * redirect: 重定向
 */

const routes = [
  {
    path: "/",
    redirect: 'home',  //重定向到首页
    hidden: true
  },
  {
    path: '',
    name: '',
    component: layOut,
    children: [{
      path: 'home',
      name: 'home',
      meta: {
        title: '首页',
        icon: 'el-icon-info'
      },
      component: () => import('@/views/Home.vue'),
    }]
  },
  {
    path: '/one',
    name: 'one',
    meta: {
      title: "一级单个",
      icon: "el-icon-goods",
    },
    component: layOut,
    children: [{
      path: 'oone',
      name: 'oone',
      meta: {
        title: '一单',
        icon: 'el-icon-info'
      },
      component: () => import('@/views/components/oneOne/oneOne.vue')
    }]
  },
  {
    path: '/two',
    name: 'test',
    meta: {
      title: "二级下单个",
      icon: "el-icon-goods",
    },
    component: layOut,
    children: [{
      path: 'tone',
      name: 'tone',
      meta: {
        title: '二下单',
        icon: 'el-icon-info'
      },
      component: () => import('@/views/components/twoOne/twoOne.vue')
    }, {
      path: 'tone2',
      name: 'tone2',
      meta: {
        title: '二下单2',
        icon: 'el-icon-info'
      },
      hidden: true,   //可用于多级菜单时只有一个下级菜单的显隐
      component: () => import('@/views/components/twoOne/twoOne.vue'),
    }]
  },
  {
    path: '/twomore',
    name: 'twomore',
    meta: {
      title: "二级下多个",
      icon: "el-icon-goods",
    },
    component: layOut,
    children: [{
      path: 'twomore1',
      name: 'twomore1',
      meta: {
        title: '二下多1',
        icon: 'el-icon-info'
      },
      component: () => import('@/views/components/twomore/twomore1.vue')
    }, {
      path: 'twomore2',
      name: 'twomore2',
      meta: {
        title: '二下多2',
        icon: 'el-icon-info'
      },
      // hidden: true,   //可用于二级菜单时只有一个下级菜单的显隐
      component: () => import('@/views/components/twomore/twomore2.vue'),
    }]
  },
  {
    path: "/threemore",
    name: "threemore",
    component: layOut,
    meta: {
      title: "三下级多个",
      icon: "el-icon-success",
    },
    children: [

      {
        path: "/threemore1",
        name: "threemore1",
        meta: {
          title: "三一",
          icon: "el-icon-goods",
        },
        component: thirdLay,
        children: [{
          path: "threemore11",
          name: "threemore11",
          meta: {
            title: "三一一",
            icon: "el-icon-mobile-phone",
          },
          component: () => import('@/views/components/threemore/threemore11.vue'),
        },
        {
          path: "threemore12",
          name: "threemore12",
          meta: {
            title: "三一二",
            icon: "el-icon-service",
          },
          component: () => import('@/views/components/threemore/threemore12.vue'),
        }
        ]
      },
      {
        path: "/threemore2",
        name: "threemore2",
        meta: {
          title: "三二",
          icon: "el-icon-upload",
        },
        component: thirdLay,
        children: [{
          path: "threemore21",
          name: "threemore21",
          meta: {
            title: "三二一",
            icon: "el-icon-mobile-phone",
          },
          component: () => import('@/views/components/threemore/threemore21.vue'),
        },
        {
          path: "threemore22",
          name: "threemore22",
          meta: {
            title: "三二二",
            icon: "el-icon-mobile-phone",
          },
          hidden: true,   //可用于二级菜单时只有一个下级菜单的显隐
          component: () => import('@/views/components/threemore/threemore22.vue'),
        }
        ]
      },
      {
        path: "threemore3",
        name: "threemore3",
        meta: {
          title: "三三",
          icon: "el-icon-upload",
        },
        component: () => import('@/views/components/threemore/threemore3.vue'),
      },
    ]
  }
];

const router = new VueRouter({
  routes
});

export default router;

2. 页面整体布局(layOut.vue):

<template>
  <div class="layOut">
    <el-container>
      <el-header>
        <head-top></head-top>
      </el-header>
      <el-container>
        <el-aside width="230px">
          <asile-left></asile-left>
        </el-aside>
        <el-main>
          <main-con></main-con>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import headTop from "@/views/layOut/pages/headTop.vue";
import asileLeft from "@/views/layOut/pages/asileLeft.vue";
import mainCon from "@/views/layOut/pages/mainCon.vue";
export default {
  name: "layOut",
  components: {
    headTop,
    asileLeft,
    mainCon,
  },
};
</script>

<style lang='less' scoped>
/deep/ .el-header,
/deep/ .el-footer {
  background-color: #b3c0d1;
  color: #333;
  text-align: center;
  line-height: 60px;
}

/deep/ .el-aside {
  background-color: #d3dce6;
  color: #333;
  text-align: left;
  line-height: 200px;
  width: 230px !important;
}

/deep/ .el-main {
  background-color: #e9eef3;
  color: #333;
  text-align: center;
  padding: 0 !important;
  line-height: calc(100vh - 116px);
}

body > .el-container {
  margin-bottom: 40px;
}

/deep/ .el-container:nth-child(5) .el-aside,
/deep/ .el-container:nth-child(6) .el-aside {
  line-height: 260px;
}

/deep/ .el-container:nth-child(7) .el-aside {
  line-height: 320px;
}

</style>

3. 侧边菜单组件(asileLeft.vue):

<template>
  <div class="asileLeft">
    <el-aside class="slider_container">
        <el-menu class="sub_meuns_wapper" mode="vertical" :default-active="$route.path" background-color="#304156" text-color="#fff" active-text-color="#409EFF">
          <!-- 菜单组件 -->
          <side-Meuns :menuList="menuList"></side-Meuns>
        </el-menu>
      </el-aside>
  </div>
</template>

<script>
import sideMeuns from './sideMeuns';
export default {
  name: "asileLeft",
  data(){
    return {
      menuList: []
    }
  },
  components: { sideMeuns },
  methods:{
    
  },
  created(){
    console.log('1',this.$route.path);
    this.menuList = this.$router.options.routes
  }
};
</script>

<style lang='less' scoped>
</style>


4.路由菜单布局逻辑(sideMeuns.vue):

<template>
  <div class="">
    <!-- 遍历路由表,生成左侧菜单 -->
    <div v-for="(item, index) in meuns" :key="index">
      <template v-if="!item.hidden">
        <!-- 一级菜单的情况 -->
        <template v-if="item.children && item.children.length === 1">
          <router-link :to="item.path + '/' + item.children[0].path">
            <!--           index跟浏览器地址对应,这样菜单才能显示选中状态  -->
            <el-menu-item :index="item.path + '/' + item.children[0].path">
              <template slot="title">
                <!-- 设置icon -->
                <i
                  v-if="item.children[0].meta.icon"
                  :class="item.children[0].meta.icon"
                ></i>
                <!-- 菜单名称 -->
                {{ item.children[0].meta.title }}
              </template>
            </el-menu-item>
          </router-link>
        </template>
        <!-- 一级菜单的情况 end-->
        <!-- 多级菜单 -->
        <template v-else>
          <el-submenu :index="item.path">
            <template slot="title">
              <i :class="item.meta.icon"></i>
              {{ item.meta.title }}
            </template>
            <!-- 遍历子菜单 -->
            <div
              v-for="(itemChild, indexChild) in item.children"
              :key="indexChild"
            >
              <template v-if="!itemChild.hidden">
                <!-- 当发现存在3级或大于3级菜单时,重新遍历当前组件 -->
                <template
                  v-if="itemChild.children && itemChild.children.length > 0"
                >
                  <side-meuns
                    :menuList="[itemChild]"
                    class="nest-menu"
                  ></side-meuns>
                </template>
                <!-- 2级菜单时-->
                <template v-else>
                  <router-link :to="item.path + '/' + itemChild.path">
                    <el-menu-item :index="item.path + '/' + itemChild.path">
                      <i
                        v-if="itemChild.meta.icon"
                        :class="itemChild.meta.icon"
                      ></i>
                      {{ itemChild.meta.title }}</el-menu-item
                    >
                  </router-link>
                </template>
              </template>
              <!-- 遍历子菜单 end-->
            </div>
          </el-submenu>
        </template>
        <!-- 多级菜单 end-->
      </template>
    </div>
  </div>
</template>
<script>
export default {
  name: "sideMeuns",
  props: {
    menuList: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      meuns: "",
    };
  },

  mounted() {
    this.meuns = this.menuList;
    console.log(this.meuns);
  },
};
</script>

6.友情提醒:拉取项目后别忘记先npm install 后安装依赖再执行 npm run serve运行项目哦.

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值