最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue addRoutes實現(xiàn)動態(tài)權(quán)限路由菜單的示例

 更新時間:2018年05月15日 11:22:59   作者:巴謝爾托夫斯基  
本篇文章主要介紹了vue addRoutes實現(xiàn)動態(tài)權(quán)限路由菜單的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

需求

最近接手一個后臺管理系統(tǒng),需要實現(xiàn)導航菜單從后臺拉取的效果;根據(jù)登錄用戶的權(quán)限不同分別拉出來的導航菜單也不一樣,另外可操作的界面也存在區(qū)別。

問題

因為后臺管理系統(tǒng)是準備使用vue+vue-router+element-ui+vuex的搭配來做的,可是單頁應用在進入頁面之前就已經(jīng)將vue-router實例化并且注入vue實例中了,所以在進入登錄頁面的時候舊沒辦法在重新定制路由了。接下來各種百之谷之,發(fā)現(xiàn)vue-router在2.0版本中提供了addRoutes方法添加路由,希望的曙光出現(xiàn)。

經(jīng)過一番折騰終于實現(xiàn)了功能,記錄下來便于回顧,也希望能幫助到同樣有需求的同志。

思路

1、首先在本地配置好固定不變的路由地址,例如登錄,404這些頁面,如下:

import Vue from 'vue'
import Router from 'vue-router'
import store from '@/vuex/store'
Vue.use(Router)

let router = new Router({
 routes: [
  {
   path: '/login',
   name: 'login',
   meta: {requireAuth: false},
   // 模塊使用異步加載
   component: (resolve) => require(['../components/login/login.vue'], resolve)
  }]
})
// 攔截登錄,token驗證
router.beforeEach((to, from, next) => {
 if (to.meta.requireAuth === undefined) {
  if (store.state.token) {
   next()
  } else {
   next({
    path: '/login'
   })
  }
 } else {
  next()
 }
})
export default router

配置好這些固定的路由后我們才能夠到登錄頁面,不然是無法繼續(xù)下去的。

2、然后重要的一步,我們需要跟后端老鐵約定好需要返回的權(quán)限菜單列表信息;首先這里我們先分析一下自己需要的路由結(jié)構(gòu),這里以我自己的路由作為例子。如果是我自己直接定義路由的話,會是以下結(jié)構(gòu):

let router = new Router({
 routes: [
  {
   path: '/login',
   name: 'login',
   meta: {requireAuth: false},
   component: (resolve) => require(['../components/login/login.vue'], resolve)
  },
  {
    path: '/',
    redirect: '/layout'
  },
  {
    path: '/layout',
    component: (resolve) => require(['../layout.vue'], resolve),
    children: [
      {
        path: 'index', 
        meta: {
          type: '1',    //控制是否顯示隱藏 1顯示,2隱藏
          code: 00010001, // 后面需要控制路由高亮
          title: '首頁',  // 菜單名稱
          permissonList: [] // 權(quán)限列表
        }
        component: (resolve) => require(['@/components/index/index.vue'], resolve)
      },
      {
      ...
      }   
    ]
  }]
})

根據(jù)以上結(jié)構(gòu)分析,其實真正需要動態(tài)配置的路由其實是/layout下面的children部分,所以需要后端返回給我們包含所有路由的一個數(shù)組就可以了


返回的數(shù)據(jù)中rootList中是一級導航的列表,一級導航實際是沒有路由功能,只是作為切換二級菜單的觸發(fā)器,subList才是我們真正需要的路由信息。

3、拿到權(quán)限路由信息后,需要我們在本地對數(shù)據(jù)進行處理組裝成我們需要的數(shù)據(jù):

// 登錄
   login () {
    let params = {
     account: this.loginForm.username,
     password: encrypt(this.loginForm.password)
    }
    this.loading = true
    this.$http.post(this.$bumng + '/login', this.$HP(params))
     .then((res) => {
      this.loging = false
      console.info('菜單列表:', res)
      if (res.resultCode === this.$state_ok) {
       // 合并一級菜單和二級菜單,便于顯示
       let menus = handleMenu.mergeSubInRoot(res.rootList, res.subList)
       // 本地化處理好的菜單列表
       this.saveRes({label: 'menuList', value: menus})
       // 根據(jù)subList處理路由
       let routes = handleMenu.mergeRoutes(res.subList)
       // 本地化subList,便于在刷新頁面的時候重新配置路由
       this.saveRes({label: 'subList', value: res.subList})
       // 防止重復配置相同路由
       if (this.$router.options.routes.length <= 1) {
        this.$router.addRoutes(routes)
        // this.$router不是響應式的,所以手動將路由元注入路由對象
        this.$router.options.routes.push(routes)
       }
       this.$router.replace('/layout/index')
      }
     })
     .catch((err) => {
      this.loging = false
      console.error('錯誤:', err)
     })
   },

處理菜單列表和subList的方法:mergeSubInRoot 和 mergeRoutes

const routes = [
 {
  path: '/',
  redirect: '/layout'
 },
 {
  path: '/layout',
  component: (resolve) => require(['../layout.vue'], resolve),
  children: []
 }
]
export default {
 /**
  * 合并主菜單和子菜單
  * @param: rootList [Array] 主菜單列表
  * @param: subList [Array] 子菜單
  * */
 mergeSubInRoot (roots, subs) {
  if (roots && subs) {
   for (let i = 0; i < roots.length; i++) {
    let rootCode = roots[i].code
    roots[i].children = []
    for (let j = 0; j < subs.length; j++) {
     if (rootCode === subs[j].code.substring(0, 4)) {
      roots[i].children.push(subs[j])
     }
    }
   }
  }
  return roots
 },
 /**
  * 合并遠程路由到本地路由
  * @param: subList [Array] 遠程路由列表
  * @param: routes [Array] 本地路由列表
  * */
 mergeRoutes (subs) {
  if (subs) {
   for (let i = 0; i < subs.length; i++) {
    let temp = {
     path: subs[i].actUrl,
     name: subs[i].actUrl,
     component: (resolve) => require([`@/components/${subs[i].component}.vue`], resolve),
     meta: {
      type: subs[i].type,
      code: subs[i].code,
      title: subs[i].name,
      permissionList: subs[i].permissionList
     }
    }
    routes[1].children.push(temp)
   }
  }
  return routes
 }
}

至此我們已經(jīng)將權(quán)限路由成功配置進本地路由了,我的系統(tǒng)登錄進入如下

后續(xù)優(yōu)化

1、菜單列表的顯示以及二級導航切換:

<template>
  <div class="mainMenu">
   <el-menu
    class="menubar"
    mode="horizontal"
    :default-active="activeCode"
    background-color="#545c64"
    text-color="#fff"
    active-text-color="#ffd04b">
    <el-menu-item :index="item.code | splitCode" v-for="item in menuList" :key="item.code" @click="switchSubMenu(item)" v-if="item.code !== '0008'">
     <i :class="`iconfont icon-${item.imgUrl}`"></i>
     <span slot="title">{{item.name}}</span>
    </el-menu-item>
   </el-menu>
  </div>
</template>

<script type="text/ecmascript-6">
 import {mapState, mapMutations} from 'vuex'
 export default {
  name: 'menu',
  data () {
   return {
    msg: 'Welcome to Your Vue.js App'
   }
  },
  computed: {
   ...mapState(['menuList']),
   activeCode () {
     // 通過code保證在切換字路由的情況下一級路由也是高亮顯示
    return this.$route.meta.code.substring(0, 4)
   }
  },
  methods: {
   ...mapMutations(['saveRes']),
   // 切換二級路由
   switchSubMenu (route) {
    console.info('路由:', route)
    if (route.actUrl !== 'index') {
     // 用currentSubMenu控制二級路由數(shù)據(jù) 
     this.saveRes({label: 'currentSubMenu', value: route.children})
     this.$router.push(`/layout/${route.children[0].actUrl}`)
    } else {
     // 不存在二級路由隱藏二級 
     this.saveRes({label: 'currentSubMenu', value: ''})
     this.$router.push(`/layout/${route.actUrl}`)
    }
   }
  },
  filters: {
   splitCode (code) {
    return code.substring(0, 4)
   }
  }
 }
</script>

2、防止刷新路由丟失;由于在刷新的時候單頁應用會重新初始化,這時候所有配置的路由都會丟失,一朝回到解放前,只有本地配置的路由能夠跳轉(zhuǎn)。這時候我們可以在app.vue(ps:不論在哪里進行刷新,app.vue都會執(zhí)行)中執(zhí)行如下代碼:

<script>
 import {decrypt} from '@/libs/AES'
 import handleMenu from '@/router/handleMenu'
 export default {
  name: 'app',
  created () {
   // 當this.$router.options.routes的長度為1,且本地緩存存在菜單列表的時候才重新配置路由
   if (this.$router.options.routes.length <= 1 && sessionStorage.getItem('subList')) {
    let subList = JSON.parse(decrypt(sessionStorage.getItem('subList')))
    let routes = handleMenu.mergeRoutes(subList)
    this.$router.addRoutes(routes)
    // this.$router不是響應式的,所以手動將路由元注入路由對象
    this.$router.options.routes.push(routes)
   }
  }
 }
</script>

這樣即使刷新,也會重新配置路由了。

3、關(guān)于頁面按鈕級別控制,可以自定義一個指令,去做這件事情。因為我們已經(jīng)權(quán)限列表放入了相應路由的meta對象中,所以我們可以很方便的在每個頁面回去到當前用戶在當前頁面所擁有的權(quán)限

參考官方文檔自定義指令

結(jié)語

打完收工,得虧vue-router2中添加了addRoutes的方法,不然

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue + CSS實現(xiàn)漸變柵格進度條效果

    Vue + CSS實現(xiàn)漸變柵格進度條效果

    基于Vue和CSS實現(xiàn)漸變柵格進度條,通過劃分柵格單元、顏色漸變、標簽與刻度的絕對定位來實現(xiàn)高度靈活和交互性,進度條劃分為多個柵格,每個單元格顏色漸變并且連續(xù),可以根據(jù)不同的場景配置個性化屬性,具有極高的靈活度和交互性,感興趣的朋友一起看看吧
    2025-03-03
  • 在vue中安裝使用vux的教程詳解

    在vue中安裝使用vux的教程詳解

    這篇文章主要介紹了在vue中安裝使用vux的教程,本文給大家記錄了vuex的安裝使用過程,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2018-09-09
  • 解決vue-router在同一個路由下切換,取不到變化的路由參數(shù)問題

    解決vue-router在同一個路由下切換,取不到變化的路由參數(shù)問題

    今天小編就為大家分享一篇解決vue-router在同一個路由下切換,取不到變化的路由參數(shù)問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Vue3 如何使用CryptoJS加密

    Vue3 如何使用CryptoJS加密

    CryptoJS是一個強大的JavaScript庫,它提供了多種加密解密功能,尤其是AES加密方法,使用CryptoJS,我們可以有效地保護數(shù)據(jù)安全,防止信息泄露,通過簡單的安裝和函數(shù)編寫,本文給大家介紹Vue3 如何使用CryptoJS加密,感興趣的朋友一起看看吧
    2024-10-10
  • vue移動端自適應適配問題詳解

    vue移動端自適應適配問題詳解

    這篇文章主要介紹了vue移動端自適應適配問題,本文通過實例代碼詳解給大家介紹的非常詳細,需要的朋友可以參考下
    2021-04-04
  • vue3父子組件通信、兄弟組件實時通信方式

    vue3父子組件通信、兄弟組件實時通信方式

    這篇文章主要介紹了vue3父子組件通信、兄弟組件實時通信方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Mac下安裝vue

    Mac下安裝vue

    本文給大家詳細介紹了Mac下安裝vue的方法,本文圖文并茂給大家介紹的非常詳細,需要的朋友可以參考下
    2018-04-04
  • 基于Vue實例對象的數(shù)據(jù)選項

    基于Vue實例對象的數(shù)據(jù)選項

    下面小編就為大家?guī)硪黄赩ue實例對象的數(shù)據(jù)選項。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 解決vue props傳Array/Object類型值,子組件報錯的情況

    解決vue props傳Array/Object類型值,子組件報錯的情況

    這篇文章主要介紹了解決vue props傳Array/Object類型值,子組件報錯的情況,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Vue中用watch一次監(jiān)聽多個值變化的示例詳解

    Vue中用watch一次監(jiān)聽多個值變化的示例詳解

    在Vue中,watch 本身不能監(jiān)聽多個變量,但我們可以通過返回具有計算屬性的對象然后監(jiān)聽該對象,從而實現(xiàn)一次性“監(jiān)聽多個變量”,本文給大家介紹了Vue中用watch一次監(jiān)聽兩個值變化的示例,需要的朋友可以參考下
    2024-01-01

最新評論

沾益县| 阳新县| 浪卡子县| 格尔木市| 津南区| 镶黄旗| 九江县| 东乌珠穆沁旗| 鲁山县| 得荣县| 陇西县| 通州区| 汤阴县| 巴林右旗| 鄂托克前旗| 广元市| 得荣县| 沂水县| 平阳县| 普兰店市| 哈尔滨市| 柳州市| 蒙阴县| 万荣县| 同江市| 黔西| 博野县| 五寨县| 保康县| 隆回县| 棋牌| 历史| 茂名市| 峨眉山市| 建始县| 肥东县| 宁陕县| 古蔺县| 清水河县| 南宁市| 海阳市|