您好,登錄后才能下訂單哦!
這篇文章主要介紹了ElementUI復(fù)雜頂部和左側(cè)導(dǎo)航欄怎么實(shí)現(xiàn)的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇ElementUI復(fù)雜頂部和左側(cè)導(dǎo)航欄怎么實(shí)現(xiàn)文章都會(huì)有所收獲,下面我們一起來看看吧。
描述:如圖
項(xiàng)目路徑如下圖所示:
代碼實(shí)現(xiàn):
首先在store.js中添加兩個(gè)狀態(tài):
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { topNavState: 'home', leftNavState: 'home' } export default new Vuex.Store({ state })
App.vue內(nèi)容:
<template> <div id="app"> <router-view></router-view> </div> </template> <script> export default { name: 'app' } </script>
main.js代碼:
import Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui' import store from './store.js' import 'element-ui/lib/theme-chalk/index.css' import '@/assets/iconfont.css' import '@/assets/css/style.css' Vue.config.productionTip = false Vue.use(ElementUI) new Vue({ router, store, el: '#app', render: h => h(App) })
router/index.js文件聲明路由:
其中:行程計(jì)劃、任務(wù)、通訊錄屬于首頁(yè)大板塊(topNavState=“home”);企業(yè)信息、車輛信息、部門信息都屬于enterprise這一大板塊(topNavState=“enterprise”)
import Vue from 'vue' import Router from 'vue-router' import LeftNav from '@/components/nav/leftNav.vue' import Home from '@/views/home.vue' import Dashboard from '@/views/workbench/dashboard.vue' import Mission from '@/views/workbench/mission/mission.vue' import Plan from '@/views/workbench/plan.vue' import Maillist from '@/views/workbench/maillist.vue' import EnterpriseList from '@/views/enterprise/index.vue' import EnterpriseAdd from '@/views/enterprise/add.vue' import EnterpriseDetail from '@/views/enterprise/detail.vue' import EnterpriseValidate from '@/views/enterprise/validate.vue' import VehicleManage from '@/views/vehicle/index.vue' import DeptManager from '@/views/dept/index.vue' import NotFound from '@/components/404.vue' // 懶加載方式,當(dāng)路由被訪問的時(shí)候才加載對(duì)應(yīng)組件 const Login = resolve => require(['@/views/login'], resolve) Vue.use(Router) let router = new Router({ routes: [ { path: '/login', type: 'login', component: Login }, { path: '*', component: NotFound }, { path: '/', type: 'home', // 根據(jù)type區(qū)分不同模塊(頂部導(dǎo)航) name: 'home', // 根據(jù)name區(qū)分不同子模塊(左側(cè)導(dǎo)航) redirect: '/dashboard', component: Home, menuShow: true, children: [ { path: '/dashboard', component: LeftNav, name: 'dashboard', // 當(dāng)前路由的name leaf: true, // 只有一個(gè)節(jié)點(diǎn) iconCls: 'iconfont icon-home', // 圖標(biāo)樣式class menuShow: true, children: [ { path: '/dashboard', component: Dashboard, name: '首頁(yè)', menuShow: true } ] }, { path: '/mySet', component: LeftNav, name: '我的設(shè)置', iconCls: 'el-icon-menu', menuShow: true, children: [ { path: '/mySet/plan', component: Plan, name: '行程計(jì)劃', menuShow: true }, { path: '/mySet/mission', component: Mission, name: '我的任務(wù)', menuShow: true }, { path: '/mySet/maillist', component: Maillist, name: '通訊錄', menuShow: true } ] } ] }, { path: '/enterpriseManager', type: 'enterprise', name: 'enterprise', component: Home, redirect: '/enterprise/list', menuShow: true, children: [ { path: '/enterpriseList', component: LeftNav, name: 'enterpriseList', leaf: true, // 只有一個(gè)節(jié)點(diǎn) iconCls: 'iconfont icon-home', // 圖標(biāo)樣式class menuShow: true, children: [ { path: '/enterprise/list', component: EnterpriseList, name: '企業(yè)列表', menuShow: true }, { path: '/enterprise/detail', component: EnterpriseDetail, name: '企業(yè)詳情', menuShow: false } ] }, { path: '/enterpriseAdd', component: LeftNav, name: 'enterpriseAdd', leaf: true, // 只有一個(gè)節(jié)點(diǎn) iconCls: 'el-icon-menu', menuShow: true, children: [ { path: '/enterprise/add', component: EnterpriseAdd, name: '企業(yè)添加', menuShow: true } ] }, { path: '/enterpriseValidate', component: LeftNav, name: 'enterpriseValidate', leaf: true, // 只有一個(gè)節(jié)點(diǎn) iconCls: 'el-icon-menu', menuShow: true, children: [ { path: '/enterprise/validate', component: EnterpriseValidate, name: '企業(yè)認(rèn)證', menuShow: true } ] } ] }, { path: '/vehicleManager', type: 'enterprise', name: 'vehicle', component: Home, redirect: '/vehicle/list', menuShow: true, children: [ { path: '/vehicleList', component: LeftNav, name: 'vehicleList', leaf: true, // 只有一個(gè)節(jié)點(diǎn) iconCls: 'iconfont icon-home', // 圖標(biāo)樣式class menuShow: true, children: [ { path: '/vehicle/list', component: VehicleManage, name: '車輛信息', menuShow: true } ] } ] }, { path: '/deptManager', type: 'enterprise', name: 'dept', component: Home, redirect: '/dept/list', menuShow: true, children: [ { path: '/deptList', component: LeftNav, name: 'deptList', leaf: true, // 只有一個(gè)節(jié)點(diǎn) iconCls: 'iconfont icon-home', // 圖標(biāo)樣式class menuShow: true, children: [ { path: '/dept/list', component: DeptManager, name: '部門信息', menuShow: true } ] } ] } ] }); router.beforeEach((to, from, next) => { // console.log('to:' + to.path) if (to.path.startsWith('/login')) { window.localStorage.removeItem('access-user') next() } else if(to.path.startsWith('/register')){ window.localStorage.removeItem('access-user') next() } else { let user = JSON.parse(window.localStorage.getItem('access-user')) if (!user) { next({path: '/login'}) } else { next() } } }); export default router
特別說明:
這里的路由對(duì)象router ,設(shè)置的是最多三級(jí),一級(jí)路由主要對(duì)應(yīng)的是頂部導(dǎo)航和其他無(wú)子頁(yè)面的路由,二級(jí)和三級(jí)路由分別對(duì)應(yīng)的是左側(cè)導(dǎo)航的一級(jí)和二級(jí)菜單(比如三級(jí)路由對(duì)應(yīng)的就是左側(cè)導(dǎo)航的二級(jí)菜單),二級(jí)路由設(shè)置leaf屬性,值為true表明該路由下沒有子菜單(如果該路由下的某頁(yè)面不顯示在左側(cè)導(dǎo)航,不算子菜單)。
leftNav.vue文件中主要是左側(cè)導(dǎo)航菜單加載代碼:
<template> <el-col :span="24" class="main"> <!--左側(cè)導(dǎo)航--> <aside :class="{showSidebar:!collapsed}"> <!--展開折疊開關(guān)--> <div class="menu-toggle" @click.prevent="collapse"> <i class="iconfont icon-outdent" v-show="!collapsed" title="收起"></i> <i class="iconfont icon-indent" v-show="collapsed" title="展開"></i> </div> <!--導(dǎo)航菜單--> <el-menu :default-active="$route.path" router :collapse="collapsed" ref="leftNavigation"> <template v-for="(issue,index) in $router.options.routes"> <template v-if="issue.name === $store.state.leftNavState"><!-- 注意:這里就是leftNavState狀態(tài)作用之處,當(dāng)該值與router的根路由的name相等時(shí)加載相應(yīng)菜單組 --> <template v-for="(item,index) in issue.children"> <el-submenu v-if="!item.leaf" :index="index+''" v-show="item.menuShow"> <template slot="title"><i :class="item.iconCls"></i><span slot="title">{{item.name}}</span></template> <el-menu-item v-for="term in item.children" :key="term.path" :index="term.path" v-if="term.menuShow" :class="$route.path==term.path?'is-active':''"> <i :class="term.iconCls"></i><span slot="title">{{term.name}}</span> </el-menu-item> </el-submenu> <el-menu-item v-else-if="item.leaf&&item.children&&item.children.length" :index="item.children[0].path" :class="$route.path==item.children[0].path?'is-active':''" v-show="item.menuShow"> <i :class="item.iconCls"></i><span slot="title">{{item.children[0].name}}</span> </el-menu-item> </template> </template> </template> </el-menu> </aside> <!--右側(cè)內(nèi)容區(qū)--> <section class="content-container"> <div class="grid-content bg-purple-light"> <el-col :span="24" class="content-wrapper"> <transition name="fade" mode="out-in"> <router-view></router-view> </transition> </el-col> </div> </section> </el-col> </template> <script> export default { name: 'leftNav', data () { return { collapsed: false } }, methods: { //折疊導(dǎo)航欄 collapse: function () { this.collapsed = !this.collapsed; }, // 左側(cè)導(dǎo)航欄根據(jù)當(dāng)前路徑默認(rèn)打開子菜單(如果當(dāng)前路由是三級(jí),則父級(jí)子菜單默認(rèn)打開) defaultLeftNavOpened () { let cur_path = this.$route.path; //獲取當(dāng)前路由 let routers = this.$router.options.routes; // 獲取路由對(duì)象 let subMenuIndex = 0, needOpenSubmenu = false; for (let i = 0; i < routers.length; i++) { let children = routers[i].children; if(children){ for (let j = 0; j < children.length; j++) { if (children[j].path === cur_path) { break; } // 如果該菜單下有子菜單(個(gè)數(shù)>1且設(shè)置的leaf為false才有下拉子菜單) if(children[j].children && !children[j].leaf) { let grandChildren = children[j].children; for(let z=0; z<grandChildren.length; z++) { if(grandChildren[z].path === cur_path) { subMenuIndex = j; needOpenSubmenu = true; break; } } } } } } if(this.$refs['leftNavigation'] && needOpenSubmenu) { this.$refs['leftNavigation'].open(subMenuIndex); // 打開子菜單 } }, }, mounted() { this.defaultLeftNavOpened(); } } </script>
home.vue是后臺(tái)主頁(yè)組件代碼
<template> <el-row class="container"> <!--頭部--> <el-col :span="24" class="topbar-wrap"> <div class="topbar-logo topbar-btn"> <a href="/" rel="external nofollow" rel="external nofollow" ><img src="../assets/logo.png" ></a> </div> <div class="topbar-logos" v-show="!collapsed"> <a href="/" rel="external nofollow" rel="external nofollow" >車車綜合管理</a> </div> <div class="topbar-title"> <el-row v-show="$store.state.topNavState==='home'"><!-- 注意:這里就是topNavState作用之處,根據(jù)當(dāng)前路由所在根路由的type值判斷顯示不同頂部導(dǎo)航菜單 --> <el-col :span="24"> <el-menu :default-active="defaultActiveIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect" :router="true"> <el-menu-item index="/">工作臺(tái)</el-menu-item> <el-menu-item index="/enterpriseManager">企業(yè)管理</el-menu-item> <el-menu-item index="/orderManager">訂單管理</el-menu-item> <el-menu-item index="/systemManager">系統(tǒng)管理</el-menu-item> </el-menu> </el-col> </el-row> <el-row v-show="$store.state.topNavState==='enterprise'"> <el-col :span="24"> <el-menu :default-active="defaultActiveIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect" :router="true"> <el-menu-item index="/enterpriseManager">企業(yè)信息</el-menu-item> <el-menu-item index="/vehicleManager">車輛信息</el-menu-item> <el-menu-item index="/deptManager">組織架構(gòu)</el-menu-item> </el-menu> </el-col> </el-row> </div> <div class="topbar-account topbar-btn"> <el-dropdown trigger="click"> <span class="el-dropdown-link userinfo-inner"> <i class="iconfont icon-user"></i> {{nickname}} <i class="el-icon-caret-bottom"></i></span> <el-dropdown-menu slot="dropdown"> <el-dropdown-item> <div @click="jumpTo('/user/profile')"><span >個(gè)人信息</span></div> </el-dropdown-item> <el-dropdown-item> <div @click="jumpTo('/user/changepwd')"><span >修改密碼</span></div> </el-dropdown-item> <el-dropdown-item divided @click.native="logout">退出登錄</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </el-col> <!--中間--> <transition name="fade" mode="out-in"> <router-view></router-view> </transition> </el-row> </template> <script> export default { name: 'home', data () { return { defaultActiveIndex: "/", loading: false, nickname: '', collapsed: false } }, created() {// 組件創(chuàng)建完后獲取數(shù)據(jù), // 此時(shí) data 已經(jīng)被 observed 了 this.fetchNavData(); }, methods: { handleSelect(index){ this.defaultActiveIndex = index; }, //折疊導(dǎo)航欄 collapse () { this.collapsed = !this.collapsed; }, fetchNavData () { // 初始化菜單激活項(xiàng) var cur_path = this.$route.path; //獲取當(dāng)前路由 var routers = this.$router.options.routes; // 獲取路由對(duì)象 var nav_type = "", nav_name = ""; for (var i = 0; i < routers.length; i++) { var children = routers[i].children; if(children){ for (var j = 0; j < children.length; j++) { var grand_children = children[j].children; if(grand_children){ for (var k = 0; k < grand_children.length; k++) { if (grand_children[k].path === cur_path) { nav_type = routers[i].type; nav_name = routers[i].name; break; } // 如果該菜單下還有子菜單 if(children[j].children) { let grandChildren = children[j].children; for(let z=0; z<grandChildren.length; z++) { if(grandChildren[z].path === cur_path) { nav_type = routers[i].type; nav_name = routers[i].name; break; } } } } } } } } this.$store.state.topNavState = nav_type; // 改變topNavState狀態(tài)的值 this.$store.state.leftNavState = nav_name; // 改變leftNavState狀態(tài)的值 if(nav_type == "home"){ this.defaultActiveIndex = "/"; } else { this.defaultActiveIndex = "/" + nav_name + "Manager"; } }, jumpTo(url){ this.defaultActiveIndex = url; this.$router.push(url); //用go刷新 }, logout(){ //logout let that = this; this.$confirm('確認(rèn)退出嗎?', '提示', { confirmButtonClass: 'el-button--warning' }).then(() => { //確認(rèn) localStorage.removeItem('access-user'); that.$router.go('/login'); //用go刷新 }).catch(() => {}); } }, mounted() { let user = localStorage.getItem('access-user'); if (user) { user = JSON.parse(user); this.nickname = user.nickname || ''; } }, watch: { '$route': 'fetchNavData' //監(jiān)聽router值改變時(shí),改變導(dǎo)航菜單激活項(xiàng) } } </script>
注意fetchNavData()這個(gè)方法,主要是根據(jù)當(dāng)前跳轉(zhuǎn)的路由,去找到這個(gè)路由對(duì)應(yīng)的type(對(duì)應(yīng)頂部導(dǎo)航欄的分類)和name(對(duì)應(yīng)左側(cè)導(dǎo)航欄的分類),然后保存type和name到$store中,這樣在頂部導(dǎo)航可以根據(jù)$store中的type顯示相應(yīng)的菜單,同樣在左側(cè)導(dǎo)航就可以取到這個(gè)name值并顯示相應(yīng)的左側(cè)菜單欄了。
之前寫的左側(cè)導(dǎo)航欄(leftNav.vue)的代碼有個(gè)不足的地方——當(dāng)前打開頁(yè)面是三級(jí)路由(也就是左側(cè)導(dǎo)航的二級(jí)菜單)時(shí),刷新當(dāng)前頁(yè),(在左側(cè)導(dǎo)航中)當(dāng)前路由所屬的一級(jí)菜單沒有默認(rèn)打開。
解決方案已修改,在leftNav.vue中添加defaultLeftNavOpened()方法,詳情可以回看leftNav.vue的代碼。
ElementUI+命名視圖實(shí)現(xiàn)復(fù)雜頂部和左側(cè)導(dǎo)航欄
補(bǔ)充:
今天有位細(xì)心的網(wǎng)友發(fā)現(xiàn)了一個(gè)小問題:
左側(cè)導(dǎo)航當(dāng)前激活的是非第一個(gè)菜單時(shí),切換其他頂部導(dǎo)航再切換回來,會(huì)有兩個(gè)激活的菜單。
解決:el-menu標(biāo)簽缺少default-active屬性設(shè)置,加上即可。
<el-menu :default-active="$route.path" router :collapse="collapsed" ref="leftNavigation"> <!-- ... --> </el-menu>
關(guān)于“ElementUI復(fù)雜頂部和左側(cè)導(dǎo)航欄怎么實(shí)現(xiàn)”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“ElementUI復(fù)雜頂部和左側(cè)導(dǎo)航欄怎么實(shí)現(xiàn)”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。