vue 如何通過監聽路由變化給父級路由菜單添加active樣式


 

 

1、項目需求:在項目開發中,多級菜單的情況下,勾選子菜單時,需要在父級菜單添加active樣式。

2、遇到的問題:一級路由菜單的話,點擊當前路由會自動在路由標簽上添加router-link-exact-active和router-link-active樣式。因此針對一級路由只需要改寫活躍狀態下的css樣式即可。但是在下拉菜單中,無法通過點擊子菜單的路由給父級菜單自動添加活躍狀態下的css屬於,因為就需要另外想辦法去處理。

3、解決方案分析:(記錄當時的心路歷程)

  (a)、考慮click事件添加css。給路由點擊時,添加時間,獲取當前點擊的菜單,匹配到其父級菜單,給父級菜單添加css屬性。

    (b)、通過監聽路由變化事件進行判斷。

當時第一種方案是一開始就想到的,但是經過分析舊的這種方法不可取,click事件需要把子菜單和父菜單做了對應的綁定,以后父級菜單命名修改也不方便,於是就想到監聽路由變化來判斷當前的頁面。一開始是打算在路由守衛處做監聽,判斷to的path是否是需要渲染父級菜單的子菜單,通過vuex定義全局變量,在頂部的組件頁面做監聽全量變量的變化做判斷。由於這種做法需要路由守衛的配合,耦合性比較高,不利於以后修改。經常搜索,才發現可以在組件頁面內部直接監聽路由的變化。

4、解決方案:

  (a)、在菜單組件內部watch監聽路由變化。

  (b)、在路由表文件router.js中給需要渲染父級菜單的子菜單中添加meta屬性,並在meta中添加routerParent屬性,用於標識需要監聽的父級對象。

  (c)、在菜單組件內部,定義一個clickMenuNum數據,具體值為數字,用數字用於表示當前需要渲染的父級菜單。

  (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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM