之前的导航栏是静态写死的,现在我们需要将其改为动态的:路由修改后,导航栏也随之修改,页面根据路由进行跳转。

分析代码

原SideBar.vue中导航栏代码

<el-menu
      default-active="3-1"
      class="el-menu-vertical-demo"
      @open="isOpen"
      @close="isClose"
      :collapse="isCollapse">

      <el-menu-item index="1">
        <div class="nav-first">
          <i class="el-icon-setting"></i>
          <span slot="title">首页</span>
        </div>
      </el-menu-item>

      <el-submenu index="2">
          <template slot="title">
            <div class="nav-first">
              <i class="el-icon-location"></i>
              <span slot="title">导航一</span>
            </div>
          </template>
          <el-menu-item index="2-1">
            <span slot="title"><span class="dot"></span>选项一</span>
          </el-menu-item>
          <el-menu-item index="2-2">
            <span slot="title"><span class="dot"></span>选项2</span>
          </el-menu-item>
          <el-menu-item index="2-3">
            <span slot="title"><span class="dot"></span>选项一</span>
          </el-menu-item>
          <el-submenu index="2-4">
            <span slot="title"><span class="dot"></span>选项4</span>
            <el-menu-item index="1-4-1">选项1</el-menu-item>
          </el-submenu>
        </el-submenu>

      <el-submenu index="3">
        <template slot="title">
          <div class="nav-first">
            <i class="el-icon-location"></i>
            <span slot="title">测试页面</span>
          </div>
        </template>
        <el-menu-item index="3-1" @click="$router.push('/3-1')">
          <span slot="title"><span class="dot"></span>testAxios</span>
        </el-menu-item>
        <el-menu-item index="3-2" @click="$router.push('/3-2')">
          <span slot="title"><span class="dot"></span>testMock</span>
        </el-menu-item>
        <el-menu-item index="3-3" @click="$router.push('/3-3')">
          <span slot="title"><span class="dot"></span>主题测试</span>
        </el-menu-item>
      </el-submenu>

      <!-- <el-menu-item index="4">
        <div class="nav-first">
          <i class="el-icon-document"></i>
          <span slot="title">404</span>
        </div>
      </el-menu-item> -->

        <el-menu-item index="4" disabled>
          <div class="nav-first">
            <i class="el-icon-document"></i>
            <span slot="title">导航三</span>
          </div>
        </el-menu-item>
        <el-menu-item index="5">
          <div class="nav-first">
            <i class="el-icon-setting"></i>
            <span slot="title">导航四</span>
          </div>
        </el-menu-item>

    </el-menu>

分析代码得:

elementplus导航菜单下面白色边框去掉 element ui 导航_二级

每一级导航都有不一样的写法,那我们可以设置一些属性来控制不同级数的导航的不同写法:

elementplus导航菜单下面白色边框去掉 element ui 导航_二级_02

并且有些路由比如Login不需要在导航栏显示,所以添加一个属性:isHidden,当isHidden未true时,不在导航栏显示。

导航栏中显示的文字和一级导航需要的图标可以通过添加一个对象meta来控制。

elementplus导航菜单下面白色边框去掉 element ui 导航_二级_03

确定路由的写法如下:

  • 不需要在导航栏显示
{
      path: '/', //http://localhost:8081/#/
      name: 'Home',  
      component: Home, //import的组件名
      isHidden:true, //不在导航列表中显示
      redirect: '/menu1', //当路由未匹配时重定向,可作初始化显示页面设置
    },
    {
      path: '/Login', 
      name: 'Login',
      component: Login,
      isHidden:true //不在导航列表中显示
    },
  • 一级菜单
{
      path: '/menu3',
      component: Home,   //是Home页面的布局
      name: 'menu3',   
      redirect:'/menu3-1', //当路由未匹配时重定向,可作初始化显示页面设置
      meta: {
        title: '二级导航menu3',
        icon: 'el-icon-document'
      },
      children: [
        {
            path: '/menu3-1',
            name: 'menu3-1',
            meta: {
                title: 'menu3-1'
            },
            component: resolve => require(['@/views/uiMenu/Ui.vue'], resolve),
        }
      ]
    }

这里说明一下为什么要这样写,而不能直接像前面——不在导航栏显示 的那样写,因为一级导航页面需要通过Home页面打开,若按照前面的写法,是重新打开一个新页面,比如登录页面,布局和Home完全无关。

  • 二级菜单
{
      path: '/menu2',
      component: Home,
      name: 'menu2',
      leaf:true,//有二级路由
      meta: {
        title: '测试页面',
        icon: 'el-icon-location'
      },
      children: [
        {
            path: '/menu2-1',
            name: 'menu2-1',
            meta: {
                title: 'TestAxios'
            },
            component: resolve => require(['@/views/testPages/TestAxios.vue'], resolve),
        },
        {
            path: '/menu2-2',
            name: 'menu2-2',
            meta: {
                title: 'TestMock'
            },
            component: resolve => require(['@/views/testPages/TestMock.vue'], resolve),
        },
        {
          path: '/menu2-3',
          name: 'menu2-3',
          meta: {
              title: '主题测试'
          },
          component: resolve => require(['@/views/testPages/TestUI.vue'], resolve),
        }
      ]
    },

一级和二级的区别在于二级添加了有二级菜单这个属性“ leaf:true ”, 少了重新定向这个“ redirect:'/menu3-1' ”,没有这个属性

  • 三级菜单
{
      path: '/menu1',
      component: Home,
      name: 'menu1',
      leafThree: true,//有三级路由
      meta: {
        title: '三级导航1',
        icon: 'el-icon-location'
      },
      children: [
        {
          path: '/menu1-1',
          name: 'menu1-1',
          meta: {
              title: '三级导航1-1'
          },
          component: Mrouter,
          leaf: true,//有二级路由
          children:[
            {
                path: '/menu1-1-1',
                name: 'menu1-1-1',
                meta: {
                    title: '三级导航1-1-1'
                },
                component: resolve => require(['@/views/testPages/menu1/Menu1-1-1.vue'], resolve),
            }
          ]
        },

        {
          path: '/menu1-2',
          name: 'menu1-2',
          meta: {
              title: '三级导航1-2'
          },
          component: resolve => require(['@/views/testPages/menu1/Menu1-2.vue'], resolve),
        }
      ]
    },

二级和三级的区别在于一级目录添加了有三级菜单这个属性“ leafThree:true ”, 二级children中多了“ leaf: true ” 和 在component处修改为“ component: Mrouter ”,并添加children

修改 router/index.js

import Vue from 'vue'
import Router from 'vue-router'

//页面布局
import Home from '@/views/Home'  //页面布局
import Mrouter from '@/views/common/main/Mrouter'  //路由承载公共组件

//单个页面
import NotFound from '@/views/err/404'  //404页面
import Login from '@/views/login/Login' //登录页面



Vue.use(Router)

const router = new Router({
  mode: 'history',
  routes: [
    {
      path: '/', //http://localhost:8081/#/
      name: 'Home',  
      component: Home, //import的组件名
      isHidden:true, //不在导航列表中显示
      redirect: '/menu1', //当路由未匹配时重定向,可作初始化显示页面设置
    },
    {
      path: '/Login', 
      name: 'Login',
      component: Login,
      isHidden:true //不在导航列表中显示
    },
    {
      path: '/404', 
      name: 'NotFound',
      component: NotFound,
      isHidden:true//不在导航列表中显示
    },

    {
      path: '/menu1',
      component: Home,
      name: 'menu1',
      leafThree: true,//有三级路由
      meta: {
        title: '三级导航1',
        icon: 'el-icon-location'
      },
      children: [
        {
          path: '/menu1-1',
          name: 'menu1-1',
          meta: {
              title: '三级导航1-1'
          },
          component: Mrouter,
          leaf: true,//有二级路由
          children:[
            {
                path: '/menu1-1-1',
                name: 'menu1-1-1',
                meta: {
                    title: '三级导航1-1-1'
                },
                component: resolve => require(['@/views/testPages/menu1/Menu1-1-1.vue'], resolve),
            }
          ]
        },

        {
          path: '/menu1-2',
          name: 'menu1-2',
          meta: {
              title: '三级导航1-2'
          },
          component: resolve => require(['@/views/testPages/menu1/Menu1-2.vue'], resolve),
        }
      ]
    },

    {
      path: '/menu2',
      component: Home,
      name: 'menu2',
      leaf:true,//有二级路由
      meta: {
        title: '测试页面',
        icon: 'el-icon-location'
      },
      children: [
        {
            path: '/menu2-1',
            name: 'menu2-1',
            meta: {
                title: 'TestAxios'
            },
            component: resolve => require(['@/views/testPages/TestAxios.vue'], resolve),
        },
        {
            path: '/menu2-2',
            name: 'menu2-2',
            meta: {
                title: 'TestMock'
            },
            component: resolve => require(['@/views/testPages/TestMock.vue'], resolve),
        },
        {
          path: '/menu2-3',
          name: 'menu2-3',
          meta: {
              title: '主题测试'
          },
          component: resolve => require(['@/views/testPages/TestUI.vue'], resolve),
        }
      ]
    },

    {
      path: '/menu3',
      component: Home,
      name: 'menu3',   
      redirect:'/menu3-1', //当路由未匹配时重定向,可作初始化显示页面设置
      meta: {
        title: '二级导航menu3',
        icon: 'el-icon-document'
      },
      children: [
        {
            path: '/menu3-1',
            name: 'menu3-1',
            meta: {
                title: 'menu3-1'
            },
            component: resolve => require(['@/views/uiMenu/Ui.vue'], resolve),
        }
      ]
    }




  ]
})


router.beforeEach((to, from, next) => {
  //登录界面登录成功之后,会把用户信息保存在会话
  //存在时间位会话生命周期,页面关闭即失效。
  let user = sessionStorage.getItem('user');
  if(to.path == '/login') {
    //如果是访问登录界面,如果用户会话信息存在,代表已经登录过,跳转到主页
    if(user) {
      next({ path: '/'})
    } else {
      next()
    }
  } else {
    //如果访问非登录页面,且用户会话信息不存在,代表为登录,则跳转到登录页面
    if(!user) {
      next({ path: '/login' })
    } else{
      next()
    }
  }
})

export default router

修改sideBar.vue中的导航栏代码

<el-menu
      router
      default-active="$route.path"
      class="el-menu-vertical-demo"
      @open="isOpen"
      @close="isClose"
      :collapse="isCollapse">

      <template v-for="(item,index) in routes" v-if="!item.isHidden" >
          <!-- 一级菜单 -->
        <el-menu-item v-if="!item.leaf && !item.leafThree && item.children.length>0" :index="item.path"> 
          <div class="nav-first">
            <i :class="item.meta.icon"></i>
            <span slot="title">{{item.meta.title}}</span>
          </div>
        </el-menu-item>

        <!-- 二级菜单 -->
        <el-submenu :index="index+''" v-if="item.leaf">
            <template slot="title">
              <div class="nav-first">
                <i :class="item.meta.icon"></i>
                <span>{{item.meta.title}}</span>
              </div>
            </template>
            <el-menu-item v-for="child in item.children" :index="child.path" v-if="!child.isHidden"  :key="child.path">
              <span slot="title"><span class="dot"></span>{{child.meta.title}}</span>
            </el-menu-item>
        </el-submenu>

        <!-- 三级菜单 -->
        <el-submenu :index="index+''" v-if="!item.leaf && item.leafThree">
            <template slot="title">
              <div class="nav-first">
                <i :class="item.meta.icon"></i>
                <span>{{item.meta.title}}</span>
              </div>
            </template>
            <el-submenu v-for="child in item.children" :index="child.path" :key="child.path" v-if="child.leaf">
              <span slot="title"><span class="dot"></span>{{child.meta.title}}</span>
              
              <el-menu-item v-for="childThree in child.children" :index="childThree.path" :key="childThree.path">
                <span>{{childThree.meta.title}}</span>
              </el-menu-item>

            </el-submenu>
            <el-menu-item v-for="child in item.children" :index="child.path" v-if="!child.isHidden && !child.leaf"  :key="child.path">
              <span slot="title"><span class="dot"></span>{{child.meta.title}}</span>
            </el-menu-item>
        </el-submenu>
      </template>



    </el-menu>

并添加如下代码:

elementplus导航菜单下面白色边框去掉 element ui 导航_导航栏_04

刷新页面,发现修改成功!并且访问正常。

elementplus导航菜单下面白色边框去掉 element ui 导航_导航栏_05

但是
看着面包屑中英文感觉很不爽,想改成和导航栏一样的文字。so,接着改:

打开面包屑组件并修改“ item.name ” ,将其改为 “ item.meta.title ”:

elementplus导航菜单下面白色边框去掉 element ui 导航_导航栏_06


elementplus导航菜单下面白色边框去掉 element ui 导航_二级_07

查看页面,发现修改成功!

elementplus导航菜单下面白色边框去掉 element ui 导航_ico_08

但是
面包屑不包含首页?面包屑不能点击跳转页面?接着改吧!

修改面包屑代码:

<template>
    <el-breadcrumb separator="/" style="margin-bottom: 24px">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item v-for="item in levelList" :key="item.path">
        <a  @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
      </el-breadcrumb-item>
    </el-breadcrumb>

</template>
export default {
  data() {
    return {
      levelList:null
    }
  },
  created() {
    this.getBreadList()
  },
  watch:{
    $route(){
        this.getBreadList()
    }
  },
  methods:{
    getBreadList(){
        let matched=this.$route.matched.filter(item=>item.name)//$route.matched 将会是一个包含从上到下的所有对象 (副本)。
          //  const first=matched[0]
          //  if(first && first.name !=='home'){//$route.name当前路由名称;$route.redirectedFrom重定向来源的路由的名字
          //    matched=[{ path: '/', meta: { title: '首页' }}].concat(matched)
          //  }
            this.levelList=matched
    },
    handleLink(item) {
      const { redirect, path } = item
      if (redirect) {
        this.$router.push(redirect)
        return
      }
      this.$router.push(this.pathCompile(path))
    },
    pathCompile(path) {
      const { params } = this.$route
      var toPath = pathToRegexp.compile(path)//url 的正则表达式,快速填充 url 字符串的参数值。
      return toPath(params)
    },
    
  },

}

【注】在pathCompile()方法中用到了pathToRegexp,所以需要安装path-to-regexp

进入项目存放的目录,在地址栏中输入cmd,打开cmd窗口,并输入

cnpm install path-to-regexp --save

然后在面包屑组件中引入

import * as pathToRegexp from 'path-to-regexp'

查看页面,发现可以点击了!

elementplus导航菜单下面白色边框去掉 element ui 导航_二级_09

参考文献

vue&Element-ui实现的导航菜单:
vue+element-ui面包屑导航: