• <noscript id="ggggg"><dd id="ggggg"></dd></noscript>
    <small id="ggggg"></small> <sup id="ggggg"></sup>
    <noscript id="ggggg"><dd id="ggggg"></dd></noscript>
    <tfoot id="ggggg"></tfoot>
  • <nav id="ggggg"><cite id="ggggg"></cite></nav>
    <nav id="ggggg"></nav>
    成人黃色A片免费看三更小说,精品人妻av区波多野结衣,亚洲第一极品精品无码,欧美综合区自拍亚洲综合,久久99青青精品免费观看,中文字幕在线中字日韩 ,亚洲国产精品18久久久久久,黄色在线免费观看

    根據(jù)用戶權(quán)限不同,動態(tài)生成路由導(dǎo)航菜單(一)

    2019-12-27    seo達(dá)人

    首先讓我們了解一下前端路由:路由router全部配置在前端,根據(jù)用戶權(quán)限判斷可以進(jìn)入哪些頁面

    缺點(diǎn):



    vue初始化的時(shí)候需要掛載全部路由,對性能有影響

    安全性低,用戶可以在地址欄跳轉(zhuǎn)到無權(quán)訪問的頁面(可優(yōu)化)

    動態(tài)路由則是根據(jù)用戶信息獲取權(quán)限,簡單來說就是根據(jù)用戶信息獲取其對應(yīng)的權(quán)限,生成對應(yīng)的路由掛載,然后動態(tài)渲染有權(quán)限的菜單于側(cè)邊欄



    實(shí)現(xiàn)

    定義靜態(tài)路由(登錄或者公用頁面)、動態(tài)路由,vue初始化時(shí)只掛載靜態(tài)路由

    用戶登錄后,拿到用戶token,調(diào)接口拿到動態(tài)路由權(quán)限D(zhuǎn)ynamicRoutes,將DynamicRoutes和定義的動態(tài)路由比較,篩選出相應(yīng)的用戶可訪問路由表

    執(zhí)行router.addRoutes(DynamicRoutes)添加動態(tài)路由

    使用vuex存儲路由表,根據(jù)vuex中可訪問的路由渲染側(cè)邊欄sidebar

    // beforeEach中

    if (getToken() && getToken() !== 'undefined') {

      // 權(quán)限判斷

      if (!store.state.app.menuPermissions) {

        / 獲取后臺給的權(quán)限數(shù)組 /

        return new Promise((resolve, reject) => {

          getPermissionList().then(response => {

            if (response.data.stat === 1) {

              const userRouter = response.data.data

              // 檢查并生成新的路由表

              const DynamicRoutes = ChecAndSetPermissionRouter(userRouter)

              // 默認(rèn)使/重定向到第一個(gè)有效的路由

              for (let i = 0, leni = DynamicRoutes.length; i < leni; i++) {

                if (DynamicRoutes[i].children.length > 0) {

                  DynamicRoutes[i].path = '/'

                  DynamicRoutes[i].redirect = DynamicRoutes[i].children[0].path

                  break

                }

              }

              DynamicRoutes.push({ path: '', redirect: '/404', hidden: true }) // 全局404

              /
    生成左側(cè)導(dǎo)航菜單 /

              store.dispatch('SetMenuPermissions', DynamicRoutes)



              /
      動態(tài)添加路由 /

              router.addRoutes(DynamicRoutes)



              // /
    完整的路由表 /

              store.dispatch('SetRouterPemissions', [...constantRouterMap, ...DynamicRoutes])

              next(to)

            }

          }).catch(error => {

            router.push('/404')

            // /
    生成左側(cè)導(dǎo)航菜單 */

            store.dispatch('SetMenuPermissions', [])

            next()

            reject(error)

          })

        })

      }

      if (to.path === '/login') {

        next({ path: '/' })

      } else {

        next()

      }

    } else {

      if (whiteList.indexOf(to.path) !== -1) {

        next()

      } else {

        next(/login?redirect=${to.path}) // 否則全部重定向到登錄頁

      }

    }



    踩坑來了





    Q:為什么404 頁面一定要最后加載,放置在靜態(tài)路由中會怎么樣?

    放在靜態(tài)路由里,后面的所以頁面都會被攔截到404,所以應(yīng)該獲取動態(tài)路由權(quán)限之后push

    Q:權(quán)限獲取成功,不跳轉(zhuǎn)新生成的動態(tài)路由,跳404?

    beforeEach中router.addRoutes之后的next()可能會失效,因?yàn)榭赡躰ext()的時(shí)候路由并沒有完全add完成,可替換成next(to),重新進(jìn)入router.beforeEach這個(gè)鉤子,這時(shí)候再通過next()來釋放鉤子,就能確保所有的路由都已經(jīng)掛在完成了。

    Q:$router.addRoutes()動態(tài)添加的路由怎么刪除掉?

    在開發(fā)中,有新增編輯刪除菜單并要求左側(cè)邊欄菜單及時(shí)更新的需求,如果直接addRoutes,warn如下:



    解決:addRoutes之前要清除掉上次addRoutes的路由,所以操作菜單調(diào)取權(quán)限后重新初始化router,進(jìn)行matcher賦值



    // DynamicRoutes是權(quán)限路由

    const createRouter = () => new Router({

      mode: 'hash',

      routes: []

    })

    const newRouter = createRouter()

    // resetRouter()

    this.$router.matcher = newRouter.matcher

    this.$router.addRoutes(DynamicRoutes)



    Q:莫名其妙的無限循環(huán)

    vue-admin-template,遇到二級菜單children為空的權(quán)限,報(bào)錯(cuò)如下:

    解決:按照github-issues上方法,在SidebarItem.vue里改一下data就好了(沒想通為啥)



    // 更改后如下,return {}

    data() {

        this.onlyOneChild = null

        return {}

    }



    附:ChecAndSetPermissionRouter



    import { dynamicRouterMap } from '@/router'



    export function ChecAndSetPermissionRouter(permissionDatas) {

      // 獲取到權(quán)限hashmap

      var permissionHashMap = null

      permissionHashMap = GetPermissionHashMap(permissionDatas)

      // 標(biāo)記路由表

      var newDynamicRouterMap = []

      newDynamicRouterMap = objDeepCopy(dynamicRouterMap)

      newDynamicRouterMap.forEach(item => {

        MarkRouter(null, item, permissionHashMap)

      })

      // 重設(shè)路由表

      for (let i = 0; i < newDynamicRouterMap.length; i++) {

        if (ResetRouter(newDynamicRouterMap, newDynamicRouterMap[i])) {

          i-- // 注意:防止移除后索引錯(cuò)位

        }

      }

      return newDynamicRouterMap

    }

    function GetPermissionHashMap(permissionDatas) {

      var permissionHashMap = {}

      permissionDatas.forEach(item => {

        SetKeyValueOfNodes(null, item, permissionHashMap)

      })

      return Object.assign({}, permissionHashMap)

    }



    // 深拷貝,遞歸重新設(shè)置前端路由表,避免數(shù)據(jù)復(fù)用

    function objDeepCopy(source) {

      var sourceCopy = source instanceof Array ? [] : {}

      for (var item in source) {

        sourceCopy[item] = typeof source[item] === 'object' ? objDeepCopy(source[item]) : source[item]

      }

      return sourceCopy

    }



    // 為權(quán)限hashmap的屬性賦值,新增屬性tempKey/tempKey2

    function SetKeyValueOfNodes(p, c, permissionHashMap) {

      // 需要匹配的組合類型

      var tempKey = (p ? p.name : 0) + '' + c.name

      var tempKey2 = c.name + '
    ' + c.name

      // 賦值

      permissionHashMap[tempKey] = 1

      permissionHashMap[tempKey2] = 1

      // 遞歸遍歷子節(jié)點(diǎn)賦值

      if (c.children != null && c.children.length > 0) {

        c.children.forEach(item => {

          SetKeyValueOfNodes(c, item, permissionHashMap)

        })

      }

    }



    // 標(biāo)記路由表

    function MarkRouter(p, c, permissionHashMap) {

      var key = (p ? p.meta.title : 0) + '_' + c.meta.title

      // 使用拼接的key作為參考標(biāo)記去匹配有權(quán)限的路由表

      if (HasPermission(key, permissionHashMap)) {

        if (p != null) {

          p.keep = true // 保留當(dāng)前節(jié)點(diǎn)

        }

        if (c != null) {

          c.keep = true

        }

      }

      if (c.children && c.children.length > 0) {

        c.children.forEach(item => {

          MarkRouter(c, item, permissionHashMap)

        })

      }

    }



    // 校驗(yàn)后端接口是否存在當(dāng)前節(jié)點(diǎn)

    function HasPermission(key, permissionHashMap) {

      return permissionHashMap[key] === 1

    }



    // 重置路由表

    function ResetRouter(p, c) {

      if (c == null) {

        return false

      }

      if (p.children && !c.keep) {

        p.children.splice(p.children.indexOf(c), 1)

        return true

      } else if (!c.keep) {

        p.splice(p.indexOf(c), 1)

        return true

      }

      if (c.children && c.children.length > 0) {

        for (let i = 0; i < c.children.length; i++) {

          if (ResetRouter(c, c.children[i])) {

            i-- // 注意:防止移除后索引錯(cuò)位

          }

        }

      }

      return false

    }




    日歷

    鏈接

    個(gè)人資料

    存檔

    主站蜘蛛池模板: 亚洲午夜久久久久久久久久 | 亚洲爆乳WWW无码专区| 国产精品导航一区二区| 激情肏屄网| 久久精品国产99久久久古代| 毛片无码高潮喷白浆视频| 亚洲天堂久久一区av| 在线观看亚洲欧美日本专区 | 国产成人精品久久综合| 久久综合精品无码AV一区二区三区| 最新无码专区超级碰碰碰| 一本久道久综合久久鬼色| 亚洲精品5555在线| 欧美三级不卡在线播放| 男女作爱免费网站| 欧美国产日韩一区二区三区精品影视| 亚洲午夜无码毛片av久久京东热| 亚洲人成网线在线播放va | 免费精品国自产拍在线播放| 亚洲国产欧美在线人成精品一区二区| 国产精品亚洲日韩欧美色窝窝色欲 | 国产精品va无码免费| 国产精品一区二区日韩精品| 狠狠躁天天躁夜夜躁婷婷| 欧美一本大道香蕉综合视频| 一区二区二区三区av| 国产美女mm131爽爽爽毛片| 无码免费午夜福利片在线| 中文无码AV在线亚洲电影| 又大又粗又硬又黄的免费视频| 色综合久久五月天久久久| 欧美黄色电影网站| 26uuu紧急升级最新消息| 人妻少妇无码精品专区| 亚洲综合极品香蕉久久网| 国产乱子伦手机在线| 精品国产三级大全在线观看| 91精品国产午夜福利在线观看| 亚洲精品tv夜色在线影院| 丁香六月婷婷| 国产亚洲自拍av在线|