<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在瞭解了命名檢視的用途後,發現用命名檢視來實現複雜導航更加省力。更多知識請參考這裡
這裡只說明重要設定內容,其他內容設定請參考上一篇初始版本:
或參考文末提到的github上的專案程式碼。
專案目錄如下:
1、router設定(router/index.js)如下:
import Vue from 'vue' import Router from 'vue-router' import TopNav from '@/components/nav/topNav.vue' import LeftNav from '@/components/nav/leftNav.vue' import Home from '@/views/home.vue' import Dashboard from '@/views/workbench/dashboard.vue' import MySettings from '@/views/workbench/mySettings.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' Vue.use(Router) let router = new Router({ routes: [ { path: '/', type: 'home', // 根據type區分不同模組(頂部導航) name: 'home', // 根據name區分不同子模組(左側導航) redirect: '/dashboard', component: Home, children: [ { path: '/dashboard', name: '首頁', // 當前路由的name(導航欄顯示文字) components: { default: Dashboard, top: TopNav, aside: LeftNav }, leaf: true, // 只有一個節點 iconCls: 'iconfont icon-home', // 圖示樣式class menuShow: true }, { path: '/mySet', components: { default: MySettings, top: TopNav, aside: LeftNav }, name: '我的設定', iconCls: 'el-icon-menu', menuShow: true, children: [ { path: '/mySet/plan', component: Plan, name: '行程計劃', menuShow: true }, { path: '/mySet/mission', component: Mission, name: '我的任務', 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: '/enterprise/list', name: '企業資訊', components: { default: EnterpriseList, top: TopNav, aside: LeftNav }, leaf: true, iconCls: 'el-icon-setting', menuShow: true }, { path: '/enterprise/detail', name: '企業詳情', components: { default: EnterpriseDetail, top: TopNav, aside: LeftNav }, leaf: true, iconCls: 'el-icon-setting', menuShow: false }, { path: '/enterprise/add', name: '新增企業', components: { default: EnterpriseAdd, top: TopNav, aside: LeftNav }, leaf: true, iconCls: 'el-icon-menu', menuShow: true }, { path: '/enterprise/validate', name: '企業認證', components: { default: EnterpriseValidate, top: TopNav, aside: LeftNav }, leaf: true, iconCls: 'el-icon-menu', menuShow: true } ] }, { path: '/vehicleManager', type: 'enterprise', name: 'vehicle', component: Home, redirect: '/vehicle/list', menuShow: true, children: [ { path: '/vehicle/list', name: '車輛資訊', components: { default: VehicleManage, top: TopNav, aside: LeftNav }, leaf: true, // 只有一個節點 iconCls: 'iconfont icon-home', // 圖示樣式class menuShow: true } ] }, { path: '/deptManager', type: 'enterprise', name: 'dept', component: Home, redirect: '/dept/list', menuShow: true, children: [ { path: '/dept/list', name: '部門資訊', components: { default: DeptManager, top: TopNav, aside: LeftNav }, leaf: true, // 只有一個節點 iconCls: 'iconfont icon-home', // 圖示樣式class menuShow: true } ] } ] });
特別說明:
這裡的路由物件router ,設定的是最多三級,一級路由主要對應的是頂部導航和其他無子頁面的路由,二級和三級路由分別對應的是左側導航的一級和二級選單(比如三級路由對應的就是左側導航的二級選單),二級路由設定leaf屬性,值為true表明該路由下沒有子選單(如果該路由下的某頁面不顯示在左側導航,不運算元選單)。
2、home.vue,這裡分別有name=top,aside,default三個檢視,top代表頂部導航,aside代表左側導航,剩下的default就是預設檢視,代表右側內容區
<template> <el-row class="container"> <!--頭部--> <el-col :span="24"><router-view name="top"></router-view></el-col> <el-col :span="24" class="main"> <!--左側導航--> <router-view name="aside"></router-view> <!--右側內容區--> <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> </el-row> </template> <script> export default { name: 'home', data () { return { loading: false } } } </script>
3、topNav.vue 是頂部導航選單的程式碼
<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" style="padding-left:8px;"></a> </div> <div class="topbar-logos"> <a href="/" rel="external nofollow" rel="external nofollow" style="color: #fff;">車車綜合管理</a> </div> <div class="topbar-title"> <!-- 注意:這裡就是topNavState作用之處,根據當前路由所在根路由的type值判斷顯示不同頂部導航選單 --> <el-row v-show="$store.state.topNavState==='home'"> <el-col :span="24"> <el-menu :default-active="defaultActiveIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect" :router="true"> <el-menu-item index="/">工作臺</el-menu-item> <el-menu-item index="/enterpriseManager">企業管理</el-menu-item> <el-menu-item index="/orderManager">訂單管理</el-menu-item> <el-menu-item index="/systemManager">系統管理</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">企業資訊</el-menu-item> <el-menu-item index="/vehicleManager">車輛資訊</el-menu-item> <el-menu-item index="/deptManager">組織架構</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 style="color: #555;font-size: 14px;">個人資訊</span></div> </el-dropdown-item> <el-dropdown-item> <div @click="jumpTo('/user/changepwd')"><span style="color: #555;font-size: 14px;">修改密碼</span></div> </el-dropdown-item> <el-dropdown-item divided @click.native="logout">退出登入</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </el-col> </el-row> </template> <script> import 'element-ui/lib/theme-chalk/display.css'; import {road} from '../../road.js' export default { data(){ return { loading: false, companyName: '', nickname: '', defaultActiveIndex: '/', homeMenu: false, messageCount: 5 } }, created() { road.$on('setNickName', (text) => { this.nickname = text; }); road.$on('goto', (url) => { if(url === "/login") { localStorage.removeItem('access-user'); this.$router.push(url); } }); // 元件建立完後獲取資料 this.fetchNavData(); }, methods: { jumpTo(url){ this.$router.push(url); //用go重新整理 }, handleSelect(index){ this.defaultActiveIndex = index; }, fetchNavData () { // 初始化選單啟用項 let cur_path = this.$route.path; //獲取當前路由 let routers = this.$router.options.routes; // 獲取路由物件 let nav_type = "", nav_name = ""; for (var 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) { 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; this.$store.state.leftNavState = nav_name; if(nav_type == "home"){ this.defaultActiveIndex = "/"; } else { this.defaultActiveIndex = "/" + nav_name + "Manager"; } }, logout(){ //logout this.$confirm('確認退出嗎?', '提示', { confirmButtonClass: 'el-button--warning' }).then(() => { //確認 localStorage.removeItem('access-user'); road.$emit('goto', '/login'); }).catch(() => {}); } }, mounted() { let user = window.localStorage.getItem('access-user'); if (user) { user = JSON.parse(user); this.nickname = user.nickname || ''; this.companyName = user.companyName || ''; } }, watch: { '$route': function(to, from){ // 路由改變時執行 //console.info("to.path:" + to.path); this.fetchNavData(); } } } </script>
注意fetchNavData()這個方法,主要是根據當前跳轉的路由,去找到這個路由對應的type(對應頂部導航欄的分類)和name(對應左側導航欄的分類),然後儲存type和name到$store中,這樣在topNav.vue元件可以根據$store中的type顯示相應的選單,同樣在leftNav.vue元件就可以取到這個name值並顯示相應的左側選單欄了。另外,裡面的top和aside是命名檢視,分別對應頂部導航元件和左側導航元件。
補充:topNavState和leftNavState這兩個狀態就是精髓所在,分別控制頂部和左側導航展示對應模組選單,這兩個狀態是在vuex組態檔store.js中設定的
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { collapsed: false, // 左側導航摺疊狀態 topNavState: 'home', leftNavState: 'dispatch' } export default new Vuex.Store({ state })
store.js檔案在main.js中引入:
import store from './store.js' new Vue({ router, store, el: '#app', render: h => h(App) })
4、leftNav.vue 左側導航欄(這裡的左側選單欄最多有兩級選單)
<template> <!--左側導航--> <aside :class="{showSidebar:!collapsed}"> <!--展開摺疊開關--> <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> <!--導航選單--> <el-menu :default-active="$route.path" router :collapse="collapsed" ref="leftNavigation"> <template v-for="(issue,index) in $router.options.routes"> <!-- 注意:這裡就是leftNavState狀態作用之處,當該值與router的根路由的name相等時載入相應選單組 --> <template v-if="issue.name === $store.state.leftNavState"> <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" :index="item.path" :class="$route.path==item.path?'is-active':''" v-show="item.menuShow"> <i :class="item.iconCls"></i><span slot="title">{{item.name}}</span> </el-menu-item> </template> </template> </template> </el-menu> </aside> </template> <script> export default { name: 'leftNav', data () { return { loading: false, collapsed: this.$store.state.collapsed, } }, methods: { //摺疊導航欄 collapse: function () { this.collapsed = !this.collapsed; this.$store.state.collapsed = this.collapsed; }, // 左側導航欄根據當前路徑預設開啟子選單(如果當前是二級選單,則父級子選單預設開啟) defaultLeftNavOpened () { let cur_path = this.$route.path; //獲取當前路由 let routers = this.$router.options.routes; // 獲取路由物件 let subMenuIndex = '', 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; } // 如果該選單下還有子選單 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); // 開啟子選單 } }, }, watch: { '$route': function(to, from){ // 路由改變時執行 //console.info("to.path:" + to.path); } }, mounted() { this.defaultLeftNavOpened(); }, } </script>
5、如果左側導航含有二級選單,
比如“我的設定(/mySet)”中,含有三個子選單:
路由設定如下:(具體檔案路徑及設定請看router/index.js)
{ path: '/mySet', components: { default: MySettings, top: TopNav, aside: LeftNav }, name: '我的設定', iconCls: 'el-icon-menu', menuShow: true, children: [ { path: '/mySet/plan', component: Plan, name: '行程計劃', menuShow: true }, { path: '/mySet/mission', component: Mission, name: '我的任務', menuShow: true }, { path: '/mySet/maillist', component: Maillist, name: '通訊錄', menuShow: true } ] }
此時,我們只需在父級選單對應檢視(MySettings)中新增一個router-view即可:
<template> <router-view></router-view> </template>
6、整體效果圖:
附上github地址:https://github.com/yqrong/vvproject
到此這篇關於ElementUI+命名檢視實現複雜頂部和左側導航欄的文章就介紹到這了,更多相關Element頂部和左側導航欄內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45