Vue + Node + Element UI 專案(十)_製作動態導航欄
阿新 • • 發佈:2020-12-30
之前的導航欄是靜態寫死的,現在我們需要將其改為動態的:路由修改後,導航欄也隨之修改,頁面根據路由進行跳轉。
分析程式碼
原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>
分析程式碼得:
每一級導航都有不一樣的寫法,那我們可以設定一些屬性來控制不同級數的導航的不同寫法:
並且有些路由比如Login不需要在導航欄顯示,所以新增一個屬性:isHidden,當isHidden未true時,不在導航欄顯示。
導航欄中顯示的文字和一級導航需要的圖示可以通過新增一個物件meta來控制。
確定路由的寫法如下:
- 不需要在導航欄顯示
{ 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>
並新增如下程式碼:
重新整理頁面,發現修改成功!並且訪問正常。
但是
看著麵包屑中英文感覺很不爽,想改成和導航欄一樣的文字。so,接著改:
打開面包屑元件並修改“ item.name ” ,將其改為 “ item.meta.title ”:
檢視頁面,發現修改成功!
參考文獻
vue&Element-ui實現的導航選單:https://blog.csdn.net/lucynie/article/details/100172281