< elementUi 中 封装 NavMenu 导航菜单,实现单页面侧边导航栏 >

文章目录

  • 前言
  • 一、原理
  • 二、实现案例
  • 后续补充
  • 三、效果演示
  • 往期内容


前言

在 Vue + elementUi 开发中,在大部分后台管理系统都会选择实现 “ 单页面 ” 应用,简称:SPA。但是实现单页面应用,页面布局显然很重要,在开发中,有时候需要,自己编写一个 单页面导航栏。本篇文章将简单展示! 案例仅供参考!

Tips: 虽然现如今,有着许多可以开箱即用的后台管理系统框架,如: vue-admin、Vue element admin、PigX、Antd Pro Vue等等。但是俗话说的好: “ 打铁还需自身硬 ”, 所以给需要自定义 单页面导航栏的小伙伴展示案例,希望能有所帮助!

一、原理

运用 v-for 循环遍历给定的参数,按照指定参数渲染对应的 侧边导航栏。原理较为简单,直接上案例即可。

使用到 elementUi 的 NavMenu 导航菜单组件 ,点击了解详细使用规则!

二、实现案例

> HTML模板

<template>
  <div :class="$root.themeHomeChange === '1' ? 'riskControlCenter_light' : 'riskControlCenter'">
    <div class="left">
      <el-menu :default-active="$route.query.index"
               class="el-menu-vertical"
               :text-color="$root.themeHomeChange === '1' ? '#adadad' : '#64b6fa'"
               @select="handleSelect"
               :collapse="isCollapse"
               unique-opened>
        <div v-for="item in menuList" :key="item.index">
          <el-menu-item v-if="item.children.length === 0" :index="item.index">
            <i :class="item.icon">i>
            <span slot="title">{{item.title}}span>
          el-menu-item>
          <el-submenu v-else :index="item.index">
            <template slot="title">
              <i :class="item.icon">i>
              <span v-show="!isCollapse" slot="title">{{item.title}}span>
            template>
            <el-menu-item-group>
              <div v-for="item1 in item.children" :key="item1.index">
                <el-menu-item v-if="item1.children.length === 0" :index="item1.index">
                  <i :class="item1.icon">i>
                  <span slot="title">{{item1.title}}span>
                el-menu-item>
                <el-submenu v-else :index="item1.index">
                  <template slot="title">
                    <i :class="item1.icon">i>
                    <span v-show="!isCollapse" slot="title">{{item1.title}}span>
                  template>
                  <el-menu-item-group>
                    <div v-for="item2 in item1.children" :key="item2.index">
                      <el-menu-item v-if="item2.children.length === 0" :index="item2.index">
                        <i :class="item2.icon">i>
                        <span slot="title">{{item2.title}}span>
                      el-menu-item>
                      <el-submenu v-else :index="item2.index">
                        <template slot="title">
                          <i :class="item2.icon">i>
                          <span v-show="!isCollapse" slot="title">{{item2.title}}span>
                        template>
                        <el-menu-item-group>
                          <div v-for="item3 in item2.children" :key="item3.index">
                            <el-menu-item v-if="item3.children.length === 0" :index="item3.index">
                              <i :class="item3.icon">i>
                              <span slot="title">{{item3.title}}span>
                            el-menu-item>
                          div>
                        el-menu-item-group>
                      el-submenu>
                    div>
                  el-menu-item-group>
                el-submenu>
              div>
            el-menu-item-group>
          el-submenu>
        div>
      el-menu>
      <el-button :icon="isCollapse ? 'el-icon-d-arrow-right' : 'el-icon-d-arrow-left'"
                 class="btnGroup"
                 @click="() => { isCollapse = !isCollapse; $forceUpdate() }"
                 type="primary"
      >el-button>
    div>
    
    <div
      class="right"
      :style="{
        'background': $root.themeHomeChange === '1' ? '#eef3ff' : '#05163d'
      }"
      ref="riskControlCenter">
      
    div>
  div>
    
template>

<script>
  export default {
    name: "riskControlCenter",
    data(){
      return {
        isCollapse : true,
        routerList: {},
        menuList: [
          {
            title: '总览',
            path: '/overView',
            index: '3-1',
            icon: 'el-icon-data-line',
            children: []
          },
          {
            title: '合规任务',
            path: '/overManage',
            index: '3-2',
            icon: 'el-icon-setting',
            children: []
          },
          {
            title: '防火墙',
            path: '/firewall',
            index: '3-3',
            icon: 'el-icon-film',
            children: [
              {
                title: '防火墙规则监测',
                path: '/firewallRuleMonitor',
                index: '3-3-1',
                icon: 'el-icon-set-up',
                children: []
              },
            ]
          }
    },
    mounted() {},
    created() {
      this.setRouterList(this.menuList);
      if(this.$route.path === '/riskControlCenter') {
        this.init(this.$route.query.index);
      }
    },
    watch: {
      $route(v) {
        if(v.path === '/riskControlCenter') {
          this.init(this.$route.query.index);
        }
      }
    },
    methods: {
      init(index) {
        index = index ? index : '3-1';
        this.setRouterList(this.menuList);
        this.$router.push({
          path: this.routerList[index],
          query: {
            ...this.$route.query,
            index: index,
            actNav: this.$route.query.actNav
          }
        });
      },
      // 设置回调函数,取出树状数据中的所需数据,扁平化,减少后续循环
      setRouterList(data) {
        data.forEach(item => {
          if(item.children.length === 0) {
            this.routerList[item.index] = item.path;
          } else {
            this.setRouterList(item.children);
          }
        })
      },
      handleSelect(key) {
        // console.log(key, keyPath, this.routerList[key]);
        // 获取设置的路由地址
        this.$router.push({
          path: this.routerList[key],
          query: {
            index: key,
            actNav: this.$route.query.actNav
          }
        });
      }
    }
  }
script>

<style scoped lang="scss">
  .riskControlCenter_light {
    height: 100%;
    display: flex;
    justify-content: space-between;
    /deep/ .el-menu {
      background: #fff;
      border: none;
      .el-menu-item:not(.is-active), .el-submenu__title:not(.is-active) {
        i {
          color: #4389f9;
        }
        &:hover {
          color: #4389f9;
          background: rgba($color: #4389f9, $alpha: .3);
        }
      }
      .el-menu-item.is-active {
        color: #fff;
        background: #4389f9;
      }
    }
    .left {
      width: auto;
      height: 100%;
      background: #fff;
      position: relative;
      .el-menu-vertical:not(.el-menu--collapse) {
        min-width: 150px;
        font-size: 14px;
        font-weight: bold;
      }
      .btnGroup {
        position: absolute;
        z-index: 999;
        width: 25px;
        border-radius: 0 5px 5px 0;
        padding: 14px 4px;
        right: -25px;
        top: 50%;
      }
    }
  
    .right{
      width: 100%;
      overflow-y: auto;
      background: #eef3ff;
    }
  }
  .riskControlCenter {
    height: 100%;
    display: flex;
    justify-content: space-between;
    /deep/ .el-menu, .el-menu .el-menu--popup {
      background: #1a3066;
      border: none;
      .el-menu-item, .el-submenu__title {
        &:hover {
          color: #fff;
          background: #4389f9;
        }
      }
      .el-menu-item.is-active, .el-submenu__title.is-active {
        color: #fff;
        background: #4389f9;
      }
    }
    .left {
      width: auto;
      height: 100%;
      background: #1a3066;
      position: relative;
      .el-menu-vertical:not(.el-menu--collapse) {
        min-width: 150px;
        font-size: 14px;
        font-weight: bold;
      }
      .btnGroup {
        position: absolute;
        z-index: 999;
        width: 25px;
        border-radius: 0 5px 5px 0;
        padding: 14px 4px;
        right: -25px;
        top: 50%;
      }
    }

    .right{
      width: 100%;
      overflow-y: auto;
      background: #05163d;
    }
  }
style>

案例较为粗浅,仅供参考! 其实可以再对其简化,使用循环嵌套,在Vue指令上,添加Js逻辑判断(三元运算),减少HTML结构庸余。

后续补充

自定义导航栏收起后,鼠标悬浮提示栏样式
< elementUi 中 封装 NavMenu 导航菜单,实现单页面侧边导航栏 >_第1张图片
HTML代码
需要在所需自定义样式的下拉 中设置 popper-class 属性。

<el-submenu
	:popper-class="$root.themeHomeChange === '1' ? 'submenu_diy_light' : 'submenu_diy'"
	v-else
	:index="item2.index"
	:disabled="item2.disabled"
>...el-submenu>

CSS代码


三、效果演示

< elementUi 中 封装 NavMenu 导航菜单,实现单页面侧边导航栏 >_第2张图片


往期内容

< 了解 HTTP 这一篇就够了 :什么是 HTTP ?HTTP 和 HTTPS 有什么区别 ? >

< 每日小技巧:Vue常用修饰符 >

<Javascript技巧: Javascript 是个难泡的妞,学点技巧征服 “ 她 ” >

< 谈谈对 SPA(单页面应用)的理解 >

你可能感兴趣的:(elementUi,组件封装,elementui,vue.js,vue)