一、項目需求:在項目開發中,多級菜單的狀況下,勾選子菜單時,須要在父級菜單添加active樣式。css
二、遇到的問題:一級路由菜單的話,點擊當前路由會自動在路由標籤上添加router-link-exact-active和router-link-active樣式。所以針對一級路由只須要改寫活躍狀態下的css樣式便可。可是在下拉菜單中,沒法經過點擊子菜單的路由給父級菜單自動添加活躍狀態下的css屬於,由於就須要另外想辦法去處理。vue
三、解決方案分析:(記錄當時的心路歷程)vuex
(a)、考慮click事件添加css。給路由點擊時,添加時間,獲取當前點擊的菜單,匹配到其父級菜單,給父級菜單添加css屬性。flex
(b)、經過監聽路由變化事件進行判斷。this
當時第一種方案是一開始就想到的,可是通過分析舊的這種方法不可取,click事件須要把子菜單和父菜單作了對應的綁定,之後父級菜單命名修改也不方便,因而就想到監聽路由變化來判斷當前的頁面。一開始是打算在路由守衛處作監聽,判斷to的path是不是須要渲染父級菜單的子菜單,經過vuex定義全局變量,在頂部的組件頁面作監聽全量變量的變化作判斷。因爲這種作法須要路由守衛的配合,耦合性比較高,不利於之後修改。常常搜索,才發現能夠在組件頁面內部直接監聽路由的變化。spa
四、解決方案:code
(a)、在菜單組件內部watch監聽路由變化。component
(b)、在路由表文件router.js中給須要渲染父級菜單的子菜單中添加meta屬性,並在meta中添加routerParent屬性,用於標識須要監聽的父級對象。orm
(c)、在菜單組件內部,定義一個clickMenuNum數據,具體值爲數字,用數字用於表示當前須要渲染的父級菜單。router
(d)、在父級路由中,添加:class,用於判斷是否須要添加路由活躍樣式。
(e)、在created初始化方法中,獲取當前路由,判斷。主要是用於F5刷新從新渲染。
(a)在菜單組件內部watch監聽路由變化:
1 watch: { 2 '$route'(toRouter, fromRouter) { 3 this.doMemuActive(toRouter); 4 } 5 },
1 doMemuActive(toRouter) { 2 if (toRouter && toRouter.meta && toRouter.meta.routerParent) { 3 if (toRouter.meta.routerParent == 'community') { 4 this.clickMenuNum = 5; 5 } else if (toRouter.meta.routerParent == 'intel') { 6 this.clickMenuNum = 6; 7 } else if (toRouter.meta.routerParent == 'disp') { 8 this.clickMenuNum = 7; 9 } else { 10 this.clickMenuNum = -1; 11 } 12 } else { 13 this.clickMenuNum = -1; 14 } 15 },
(b)、路由表定義 (routerParent字段表示父級代碼的字符串標誌,這樣子不須要經過一個個路徑去判斷,只須要判斷meta裏面的一個屬性便可找到其父級菜單)
1 export const constantRouterMap = [ 2 {path: '/home', component: _import('arcgisMap/home'), hidden: true,redirect: '/home/arcgisMap', 3 children: [ 4 {path: 'multipleQuery', component: _import('arcgisMap/multipleQuery'), hidden: true }, 5 6 {path: 'communitySecurity', component: _import('arcgisMap/communitySecurity'), meta: { routerParent: 'community' }, hidden: true}, 7 8 {path: 'IntelDigCtrl', component: _import('arcgisMap/IntelDigCtrl'), meta: { routerParent: 'intel' }, hidden: true }, 9 {path: 'peerAnalysis', component: _import('arcgisMap/peerAnalysis'), meta: { routerParent: 'intel' }, hidden: true }, 10 {path: 'dayInNightOut', component: _import('arcgisMap/dayInNightOut'), meta: { routerParent: 'intel' }, hidden: true }, 11 {path: 'nightBehavior', component: _import('arcgisMap/nightBehavior'), meta: { routerParent: 'intel' }, hidden: true }, 12 {path: 'frequentBehavior', component: _import('arcgisMap/frequentBehavior'), meta: { routerParent: 'intel' }, hidden: true }, 13 {path: 'personWifiMergeAls', component: _import('arcgisMap/personWifiMergeAls'), meta: { routerParent: 'intel' }, hidden: true }, 14 15 {path: 'dispGroup', component: _import('arcgisMap/dispositionModel/dispGroup/dispGroup'), meta: { routerParent: 'disp' }, hidden: true}, /*布控庫管理*/ 16 {path: 'dispTargetGroup', component: _import('arcgisMap/dispositionModel/dispTargetGroup/dispTargetGroup'), meta: { routerParent: 'disp' }, hidden: true}, /*布控庫目標分組*/ 17 {path: 'dispTarget', component: _import('arcgisMap/dispositionModel/dispTarget/dispTarget'), meta: { routerParent: 'disp' }, hidden: true}, /*布控目標管理*/ 18 ] 19 }]
(c)、在菜單組件內部,定義一個clickMenuNum數據
1 data(){ 2 return{ 3 clickMenuNum:-1, 4 } 5 },
(d)、在父級路由中,添加:class,用於判斷是否須要添加路由活躍樣式
1 <el-col :span="15" class="headerCenter flexClsNormal"> 2 <div style="width: 100%;width: 100%;overflow-y: auto;text-align: center;height: 60px;"> 3 <div><router-link to="/home/arcgisMap">首頁</router-link></div> 4 <div><router-link to="/home/actualCensus">實有人口清查</router-link></div> 5 <div style="margin: auto 0px;" > 6 <el-dropdown class="headerBarCls" @command="dropdownClick" :class="{ 'clickMenuNumTrue':clickMenuNum==5}"> 7 <span class="el-dropdown-link">社區管控<i class="el-icon-arrow-down el-icon--right"></i></span> 8 <el-dropdown-menu slot="dropdown"> 9 <el-dropdown-item command="1"> 10 <router-link to="/home/communitySecurity" >社區治安一覽表</router-link> 11 </el-dropdown-item> 12 </el-dropdown-menu> 13 </el-dropdown> 14 </div> 15 <div style="margin: auto 0px;" > 16 <el-dropdown class="headerBarCls" @command="dropdownClick" :class="{ 'clickMenuNumTrue':clickMenuNum==6}"> 17 <span class="el-dropdown-link">智能挖掘<i class="el-icon-arrow-down el-icon--right"></i></span> 18 <el-dropdown-menu slot="dropdown"> 19 <el-dropdown-item command="4"> 20 <router-link to="/home/IntelDigCtrl" >人員檔案</router-link> 21 </el-dropdown-item> 22 </el-dropdown-menu> 23 </el-dropdown> 24 </div> 25 <div style="margin: auto 0px;" > 26 <el-dropdown class="headerBarCls" @command="dropdownClick" :class="{ 'clickMenuNumTrue':clickMenuNum == 7}"> 27 <span class="el-dropdown-link">布控預警<i class="el-icon-arrow-down el-icon--right"></i></span> 28 <el-dropdown-menu slot="dropdown"> 29 <el-dropdown-item> 30 <router-link to="/home/dispGroup" >布控庫管理</router-link> 31 </el-dropdown-item> 32 </el-dropdown-menu> 33 </el-dropdown> 34 </div> 35 </div> 36 </el-col>
附加:
因爲路由菜單組件pageRoutersBar是隻渲染一次,所以須要用監聽的方法進行處理。
1 <template> 2 <div id="home"> 3 <div style="width: 100%;position: relative;" id="headerID" ref="headerID"> 4 <!--頂部菜單--> 5 <el-row> 6 <pageRoutersBar></pageRoutersBar> 7 </el-row> 8 <el-row class="addressSearch" v-if="false"> 9 <addressSearch></addressSearch> 10 </el-row> 11 </div> 12 <router-view></router-view> 13 </div> 14 </template>