Vue+Element-ui實現左側二級導航(可配置路由、所有路由層級可統一、可根據路由高亮選單項、重新整理時可自動展開定位到當前路由)
阿新 • • 發佈:2020-07-16
這裡使用的Element文件版本是2.13.1。
路由檔案index.js:
import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/components/Login'
import Main from '@/components/Main'
import Form from '@/components/Form'
import Data from '@/components/Data'
import Radio from '@/components/Radio'
import Checkbox from '@/components/Checkbox'
import Table from '@/components/Table'
import Tag from '@/components/Tag'
import Button from '@/components/Button'
import Tabs from '@/components/Tabs'
import Echarts from '@/components/Echarts'
import Dialog from '@/components/Dialog'
import Tree from '@/components/Tree'
Vue.use(Router);
let router = new Router({
mode: 'hash',
routes: [
{
path: '/',
name: 'index',
redirect: '/login'
},
{
path: '/login',
name: 'login',
component: Login,
meta: {
title: 'Login'
}
},
{
path: '/main',
alias: '/main',
name: 'main',
component: Main,
meta: {
title: 'Main'
},
children: [
{
path: '/main/form',
alias: '/form',
name: 'form',
component: Form,
meta: {
title: 'Form',
icon: 'el-icon-eleme',
requireAuth: true
},
children: [
{
path: '/main/form/radio',
alias: '/radio',
name: 'radio',
component: Radio,
meta: {
title: 'Radio',
requireAuth: true
}
},
{
path: '/main/form/checkbox',
alias: '/checkbox',
name: 'checkbox',
component: Checkbox,
meta: {
title: 'Checkbox',
requireAuth: true
}
}
]
},
{
path: '/main/data',
alias: '/data',
name: 'data',
component: Data,
meta: {
title: 'Data',
icon: 'el-icon-upload',
requireAuth: true
},
children: [
{
path: '/main/data/table',
alias: '/table',
name: 'table',
component: Table,
meta: {
title: 'Table',
requireAuth: true
}
},
{
path: '/main/data/tag',
alias: '/tag',
name: 'tag',
component: Tag,
meta: {
title: 'Tag',
requireAuth: true
}
}
]
},
{
path: '/main/button',
alias: '/button',
name: 'button',
component: Button,
meta: {
title: 'Button',
icon: 'el-icon-s-order',
requireAuth: true
}
},
{
path: '/main/tabs',
alias: '/tabs',
name: 'tabs',
component: Tabs,
meta: {
title: 'Tabs',
icon: 'el-icon-s-flag',
requireAuth: true
}
},
{
path: '/main/echarts',
alias: '/echarts',
name: 'echarts',
component: Echarts,
meta: {
title: 'Echarts',
icon: 'el-icon-s-data',
requireAuth: true
}
},
{
path: '/main/dialog',
alias: '/dialog',
name: 'dialog',
component: Dialog,
meta: {
title: 'Dialog',
icon: 'el-icon-phone',
requireAuth: true
}
}
]
},
{
path: '/tree',
alias: '/tree',
name: 'tree',
component: Tree,
meta: {
title: 'Tree',
icon: 'el-icon-s-marketing',
requireAuth: true
}
}
]
});
export default router
router.beforeEach((to, from, next) => {
let islogin = localStorage.getItem("islogin");
islogin = Boolean(Number(islogin));
if(to.path == "/login"){
if(islogin){
next("/main/form/radio");
}else{
next();
}
}else{
// requireAuth:可以在路由元資訊指定哪些頁面需要登入許可權
if(to.meta.requireAuth && islogin) {
next();
}else{
next("/login");
}
}
})
關鍵:除了login之外,其它都加上alias屬性。
Main.vue:
<template> <div id="app"> <el-container style="height: 100%;"> <el-header style="height: 80px;" :style="topBg"> <Header /> </el-header> <el-container> <el-aside width="210px" :style="leftBg"> <el-row class="tac"> <el-col :span="24"> <el-menu :default-active="$route.path" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" background-color="none" text-color="#fff" active-text-color="#ff0000" > <template v-for="route in this.$router.options.routes[2].children"> <!-- 迴圈有子目錄的選單 --> <el-submenu :key="route.alias" :index="route.alias" v-if="route.children && route.children.length" > <template slot="title"> <i :class="route.meta.icon"></i> <span>{{route.meta.title}}</span> </template> <el-menu-item-group> <router-link :to="subroute.alias" :key="subroute.alias" v-for="subroute in route.children" > <el-menu-item :index="subroute.alias">{{subroute.meta.title}}</el-menu-item> </router-link> </el-menu-item-group> </el-submenu> <!-- 迴圈有子目錄的選單 --> <!-- 迴圈沒有子目錄的選單 --> <router-link :to="route.alias" :key="route.alias" v-else-if="!route.children && route.alias != '/' && route.alias != '/login'" > <el-menu-item :index="route.alias"> <i :class="route.meta.icon"></i> <span slot="title">{{route.meta.title}}</span> </el-menu-item> </router-link> <!-- 迴圈沒有子目錄的選單 --> </template> </el-menu> </el-col> </el-row> </el-aside> <el-main> <router-view></router-view> </el-main> </el-container> </el-container> </div> </template> <script> import Header from "@/components/Header"; export default { name: "App", data() { return { leftBg: { background: "#235d8b url(" + require("../assets/left-bg.png") + ") no-repeat scroll 0 bottom" }, topBg: { background: "#235d8b url(" + require("../assets/top-bg.png") + ") no-repeat scroll right 0", height: "80px", fontSize: "32px", color: "#ffffff" } }; }, components: { Header }, methods: { handleOpen(key, keyPath) { console.log(key, keyPath); }, handleClose(key, keyPath) { console.log(key, keyPath); } } }; </script> <style> #app { font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #2c3e50; height: 100%; } .el-header, .el-footer { background-color: #b3c0d1; color: #333; line-height: 80px; } .el-aside { background-color: #d3dce6; color: #333; } .el-aside a{ text-decoration: none; } .el-menu { background: none; border-right: 0; } .el-menu-item-group .el-menu-item{ padding-left: 52px !important; } .el-menu-item.is-active { color: #409EFF; background: #ffffff; } .el-main { background-color: #ffffff; color: #333; padding: 0; } body > .el-container { margin-bottom: 40px; } .el-container:nth-child(5) .el-aside, .el-container:nth-child(6) .el-aside { line-height: 260px; } .el-container:nth-child(7) .el-aside { line-height: 320px; } </style>
其中關鍵是:
根據路由高亮list、重新整理自動展開定位路由由這個來控制:
:default-active="$route.path"
迴圈路由:
<template v-for="route in this.$router.options.routes[2].children">......</template>
另一個關鍵:
'<el-menu>'中的'<router-link></router-link>',不然沒法導航到相關元件。
Form.vue、Data.vue元件模板中需要新增'<router-view></router-view>'。