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

前端單獨實現(xiàn)vue動態(tài)路由的示例代碼

 更新時間:2024年09月13日 08:48:06   作者:你不講 wood  
Vue動態(tài)路由權(quán)限涉及根據(jù)用戶權(quán)限動態(tài)生成路由配置,實現(xiàn)此功能可增強應(yīng)用安全性、靈活性,提升用戶體驗和開發(fā)效率,本文就來介紹一下前端單獨實現(xiàn)vue動態(tài)路由的示例代碼,感興趣的可以了解一下

Vue 動態(tài)路由權(quán)限是指在 Vue 應(yīng)用程序中,根據(jù)用戶的權(quán)限動態(tài)生成和控制路由的行為。這意味著不是所有的路由都在應(yīng)用啟動時就被硬編碼到路由配置中,而是根據(jù)用戶的權(quán)限信息,在運行時動態(tài)地決定哪些路由應(yīng)該被加載和顯示。

動態(tài)路由的優(yōu)點:

  • 安全性:

    • 只有經(jīng)過驗證的用戶才能訪問其權(quán)限范圍內(nèi)的頁面。
    • 減少了由于硬編碼路由導(dǎo)致的安全漏洞。
  • 靈活性:

    • 可以根據(jù)用戶的權(quán)限動態(tài)調(diào)整應(yīng)用的結(jié)構(gòu),無需重新部署整個應(yīng)用即可調(diào)整路由。
    • 支持按需加載(懶加載),提高應(yīng)用性能。
  • 用戶體驗:

    • 只展示用戶可以訪問的菜單項,避免顯示無用鏈接,提高用戶體驗。
    • 用戶界面更加簡潔,只顯示與其角色相關(guān)的功能。
  • 可維護性:

    • 簡化了路由配置,因為不需要為每個角色單獨編寫路由配置,而是集中管理權(quán)限。
    • 更容易擴展和修改權(quán)限配置,只需更新前端的權(quán)限數(shù)據(jù)即可。
  • 開發(fā)效率:

    • 開發(fā)者只需要關(guān)注業(yè)務(wù)邏輯,而不需要關(guān)心每個角色的具體路由配置。
    • 減少了重復(fù)工作,提高了開發(fā)效率。

實現(xiàn)步驟

  • 定義靜態(tài)路由配置:

    • 在項目中定義一個包含所有可能路由的靜態(tài)配置文件或?qū)ο螅總€路由可以附加權(quán)限信息(如角色、訪問級別等)。
  • 用戶登錄與鑒權(quán):

    • 用戶登錄時,前端存儲用戶的權(quán)限信息(如角色、權(quán)限列表等)。
  • 動態(tài)生成路由:

    • 根據(jù)用戶的權(quán)限信息,從前端的靜態(tài)路由配置中篩選出用戶有權(quán)訪問的路由。
    • 使用遞歸算法或其他邏輯動態(tài)生成路由配置,并添加到 Vue Router 實例中。
  • 動態(tài)渲染菜單:

    • 根據(jù)動態(tài)生成的路由表來渲染左側(cè)菜單或頂部導(dǎo)航欄,確保只顯示用戶有權(quán)訪問的菜單項。

代碼示例

配置路由器

router/index.js

// router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Layout from '@/Layout/index.vue'


Vue.use(VueRouter)

// export const roleMap = {
//     '-1':'運維管理員',
//     '1':'普通用戶',
//     '2':'項目經(jīng)理',
//     '3':'部門管理員',
//     '4':'綜合部管理員',
//     '5':'部門領(lǐng)導(dǎo)'
// }

// 公共路由
export const routes = [
  {
    path: '/',
    name: 'redirect',
    component: Layout,
    hidden: true, // 隱藏菜單
    redirect: "/homePage", // 用戶在地址欄輸入 '/' 時會自動重定向到 /homePage 頁面
  },
  {
    path: '/homePage',
    component: Layout,
    redirect: "/homePage/index",
    meta: {
      title: "首頁",
    },
    children: [
      {
        path: 'index',
        name: 'homePageIndex',
        meta: {
          title: "首頁",
        },
        component: () => import('@/views/homePage/index.vue')
      }
    ]
  },
  {
    path: '/login',
    component: () => import('@/views/login.vue'),
    hidden: true
  },
  {
    path: '/404',
    component: () => import('@/views/error/404.vue'),
    hidden: true
  },
  {
    path: '/401',
    component: () => import('@/views/error/401.vue'),
    hidden: true
  },
]


// 動態(tài)權(quán)限路由
export const dynamicRoutes = [
  {
    path: '/admin',
    meta: {
      title: "系統(tǒng)管理",
    },
    component: Layout,
    permission: ['-1', '2', '3', '4', '5'], // all 所有角色都可以訪問  1 普通用戶  2 項目經(jīng)理  3 部門管理員  4 綜合部管理員  5  部門領(lǐng)導(dǎo)  -1 項目運維管理員
    children: [
      {
        path: 'user',
        name: 'userIndex',
        meta: {
          title: "用戶管理",
        },
        permission: ['-1', '2', '3', '4', '5'],
        component: () => import('@/views/admin/user/index.vue')
      },
      {
        path: 'role',
        name: 'roleIndex',
        meta: {
          title: "角色管理",
        },
        permission: ['-1', '2', '3', '4', '5'],
        component: () => import('@/views/admin/role/index.vue'),
        children: [
          {
            path: 'add',
            name: 'addRole',
            meta: {
              title: "添加角色",
            },
            permission: ['-1',, '3', '4', '5'],
            component: () => import('@/views/admin/user/index.vue')
          },
          {
            path: 'update',
            name: 'updateRole',
            meta: {
              title: "編輯角色",
            },
            permission: ['-1', '2', '3', '4', '5'],
            component: () => import('@/views/admin/role/index.vue')
          }
        ]
      }
    ]
  },
  {
    path: '/tableEcho',
    meta: {
      title: "表格管理",
    },
    component: Layout,
    permission: ['-1', '1', '2'],
    children: [
      {
        path: 'test',
        name: 'tableEchoIndex',
        meta: {
          title: "表格測試",
        },
        permission: ['-1', '1', '2'],
        component: () => import('@/views/tableEcho/index.vue'),
        children: [
          {
            path: 'add',
            name: 'addTable',
            hidden: true,
            meta: {
              title: "新增測試",
            },
            permission: ['-1', '2'],
            component: () => import('@/views/tableEcho/add.vue')
          }
        ]
      },
    ],
  },
]

const router = new VueRouter({
  base: process.env.BASE_URL,
  routes
})

export default router

上述代碼定義了一個公共路由 routes 和一個動態(tài)權(quán)限控制的路由 dynamicRoutes permission 數(shù)組定義了哪些角色擁有該路由權(quán)限, 將用戶分為6個角色級別, 每個角色對應(yīng)不同的角色級別,分別為

  • ‘-1’:‘運維管理員’,
  • ‘1’:‘普通用戶’,
  • ‘2’:‘項目經(jīng)理’,
  • ‘3’:‘部門管理員’,
  • ‘4’:‘綜合部管理員’,
  • ‘5’:‘部門領(lǐng)導(dǎo)’,

封裝路由守衛(wèi)

permission.js

// permission.js
import router from './router'
import store from './store'
import { Message } from 'element-ui'
import { getStore } from '@/utils/store';

const whiteList = ['/login', '/404', '/401'];

router.beforeEach((to, from, next) => {
  let token = getStore('token');

  if (token) {
    /* has token*/
    if (to.path === '/login') {
      next({ path: '/' });
    } else {
      if (store.getters.roles.length === 0) {
        // 判斷當前用戶是否已拉取完user_info信息
        store.dispatch('GetInfo').then((res) => {
          console.log('--------------', res);
          router.addRoutes(res) // 動態(tài)添加可訪問路由表
          next({ ...to, replace: true }) // hack方法 確保addRoutes已完成
        }).catch(err => {
          store.dispatch('LogOut').then(() => {
            Message.error(err)
            next(`/`)
          })
        })
      } else {
        next()
      }
    }
  } else {
    // 沒有token
    if (whiteList.indexOf(to.path) !== -1) {
      // 在免登錄白名單,直接進入
      next()
    } else {
      next(`/login`) // 否則全部重定向到登錄頁
    }
  }
})

上述代碼表示在路由的 beforeEach 函數(shù)里面調(diào)用 vuex 里面 actions 里的方法發(fā)送接口請求獲取用戶信息與用戶角色權(quán)限, 最后通過 router.addRoutes(res) 渲染路由
permission.js 文件需引入到 main.js里面

如果項目 vue-router 版本超過 3.3.0, 需要遍歷路由數(shù)組再使用 router.addRoute() 方法逐個添加路由

res.forEach( route => {
	router.addRoute(route);
})

在 vuex 里獲取用戶所擁有的權(quán)限, 過濾該權(quán)限不擁有的路由

store/index.js

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import { routes, dynamicRoutes } from "@/router";
import { login, getInfo, logout } from "@/api/user";
import { setStore, clearStore } from '@/utils/store';


Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    routes,
    token: "",
    roleType: "",
    roles: [],
    permissions: [],
    sidebarRouters: [],

  },
  getters: {
    token: state => state.token,
    roles: state => state.roles,
    permissions: state => state.permissions,
    sidebarRouters: state => state.sidebarRouters,
  },
  mutations: {
    SET_TOKEN: (state, token) => {
      state.token = token;
    },
    SET_USERINFO: (state, user) => {
      state.userInfo = user;
    },
    SET_ROLETYPE: (state, roleType) => {
      state.roleType = roleType;
    },
    SET_ROLES: (state, roles) => {
      state.roles = roles;
    },
    SET_PERMISSIONS: (state, permissions) => {
      state.permissions = permissions;
    },
    SET_ROUTE: (state, sidebarRouters) => {
      state.sidebarRouters = sidebarRouters;
    },
  },
  actions: {
    Login({ commit }, userInfo) {
      return new Promise((resolve, reject) => {
        login(userInfo).then(res => {
          setToken(res.data.token);
          setStore('token', res.data.token);
          commit('SET_TOKEN', res.data.token);
          resolve();
        }).catch(error => {
          reject(error);
        })
      })
    },
    // 獲取用戶信息
    GetInfo({ commit }) {
      return new Promise((resolve, reject) => {
        getInfo().then(res => {
          console.log('res::: ', res);
          if (res.data.code === 0 || 200) {
            const user = res.data.sysUser;
            const roleType = res.data.roleType;
            commit('SET_USERINFO', user);

            // roleType 用戶所用的權(quán)限級別 1 普通用戶  2 項目經(jīng)理  3 部門管理員  4 綜合部管理員  5  部門領(lǐng)導(dǎo)  -1 項目運維管理員
            setStore('ROLE_TYPE', roleType);
            if (res.data.roles) { // 驗證返回的roles是否為真
              commit('SET_ROLES', res.data.roles);
              commit('SET_PERMISSIONS', res.data.permissions);
            } else {
              commit('SET_ROLES', ['ROLE_DEFAULT']);
            }
            // 過濾路由
            let newRouters = filterRouter(roleType, dynamicRoutes);

            // 連接公共路由
            const sidebarRouters = routes.concat([...newRouters])

            commit('SET_ROUTE', sidebarRouters);

            resolve(sidebarRouters);
          } else {
            reject(error);
          }
        }).catch(error => {
          reject(error);
        })
      })
    },
    // 退出系統(tǒng)
    LogOut({ commit, state }) {
      return new Promise((resolve, reject) => {
        logout(state.token).then(() => {
          commit('SET_TOKEN', '')
          commit('SET_ROLES', [])
          commit('SET_PERMISSIONS', [])
          clearStore('token');
          clearStore('userInfo')
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },
  },
  modules: {
  }
})

function filterRouter(roleType, routes) {
  return routes.filter(item => {  // filter 方法創(chuàng)建一個新數(shù)組, 其包含通過所提供函數(shù)實現(xiàn)的測試的所有元素,測試未通過的元素會自動剔除
    // 如果一級路由的 permission 含有當前角色的 roleType
    if (item.permission.includes(roleType)) {

      // 如果該一級路由含有子路由時,遞歸調(diào)用該函數(shù)判斷子路由是否有權(quán)限
      if (Array.isArray(item.children) && item.children.length > 0) {

        // 遞歸調(diào)用該函數(shù),最后接受校驗通過后的子路由
        let newChildren = filterRouter(roleType, item.children);

        // 如果子路由有值,則賦值給當前路由的 children,剔除校驗不通過的子路由
        if (newChildren.length > 0) {
          item.children = newChildren;
        } else if (newChildren.length === 0) { // 如果子路由為空,則刪除該路由的 children 屬性
          delete item.children;
        }
      }

      // 最后返回 true, 表示該路由通過權(quán)限校驗
      return true;
    }
  })
}

上述代碼通過 getInfo 接口獲取用戶權(quán)限, 通過函數(shù) filterRouter 過濾掉該角色不擁有的路由, 通過 concat 方法合并 routes 公共路由, 最后通過 resolve 返回

文件布局如下

在這里插入圖片描述

下圖為頁面渲染的菜單(項目經(jīng)理角色)

在這里插入圖片描述

左側(cè)菜單實現(xiàn)參考鏈接: Elemnt-UI + 遞歸組件實現(xiàn)后臺管理系統(tǒng)左側(cè)菜單

前端結(jié)合后端接口請求實現(xiàn)動態(tài)路由參考連接: 前端 + 接口請求實現(xiàn) vue 動態(tài)路由

總結(jié)

在用戶登錄成功后從服務(wù)器獲取用戶的權(quán)限信息,在 vuex 的異步處理函數(shù)中過濾掉角色權(quán)限不存在的路由,使用 concat() 合并公共路由,最后使用 router.addRoutes(res) 動態(tài)添加可訪問的路由。這樣可以確保應(yīng)用根據(jù)用戶的權(quán)限動態(tài)加載相應(yīng)的路由,增強安全性與靈活性。

相關(guān)文章

  • ant desing vue table 實現(xiàn)可伸縮列的完整例子

    ant desing vue table 實現(xiàn)可伸縮列的完整例子

    最近在使用ant-design-vue做表格時,遇到要做一個可伸縮列表格的需求,在網(wǎng)上一直沒有找到好的方法,于是小編動手自己寫個可以此功能,下面小編把ant desing vue table 可伸縮列的實現(xiàn)代碼分享到腳本之家平臺供大家參考
    2021-05-05
  • 在Vue中實現(xiàn)文件批量下載功能

    在Vue中實現(xiàn)文件批量下載功能

    在Vue項目開發(fā)中,實現(xiàn)文件批量下載是一個常見需求,例如,在一個文檔管理系統(tǒng)中,用戶可能希望一次性下載多個相關(guān)文檔;在圖片庫應(yīng)用里,用戶可能需要批量獲取一組圖片,接下來,將介紹如何在Vue中實現(xiàn)文件批量下載功能,需要的朋友可以參考下
    2025-06-06
  • Vue項目中如何配置src文件下的@別名

    Vue項目中如何配置src文件下的@別名

    這篇文章主要介紹了Vue項目中如何配置src文件下的@別名問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 利用Vite2和Vue3實現(xiàn)網(wǎng)站國際化的全過程

    利用Vite2和Vue3實現(xiàn)網(wǎng)站國際化的全過程

    vite2已經(jīng)出來一段時間了,最近沒忍住嘗試了一下,這篇文章主要給大家介紹了關(guān)于利用Vite2和Vue3實現(xiàn)網(wǎng)站國際化的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • 基于Vue制作組織架構(gòu)樹組件

    基于Vue制作組織架構(gòu)樹組件

    最近公司在做一個基于vue開發(fā)的項目,項目需要開發(fā)一個展示組織架構(gòu)的樹組件,在網(wǎng)上搜了半天,沒有找到合適的,下面小編給大家分享一個基于Vue制作組織架構(gòu)樹組件,需要的朋友參考下吧
    2017-12-12
  • Vue.js每天必學(xué)之數(shù)據(jù)雙向綁定

    Vue.js每天必學(xué)之數(shù)據(jù)雙向綁定

    Vue.js每天必學(xué)之數(shù)據(jù)雙向綁定,如何進行綁定,如何進行數(shù)據(jù)雙向綁定,感興趣的小伙伴們可以參考一下
    2016-09-09
  • vue 實現(xiàn)axios攔截、頁面跳轉(zhuǎn)和token 驗證

    vue 實現(xiàn)axios攔截、頁面跳轉(zhuǎn)和token 驗證

    這篇文章主要介紹了vue 實現(xiàn)axios攔截、頁面跳轉(zhuǎn)和token 驗證,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • vue線上部署請求接口報錯net::ERR_CONNECTION_REFUSED

    vue線上部署請求接口報錯net::ERR_CONNECTION_REFUSED

    vue線上部署請求接口報錯net::ERR_CONNECTION_REFUSED問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue3+vite自定義封裝vue組件發(fā)布到npm包的全過程

    vue3+vite自定義封裝vue組件發(fā)布到npm包的全過程

    當市面上主流的組件庫不能滿足我們業(yè)務(wù)需求的時候,那么我們就有必要開發(fā)一套屬于自己團隊的組件庫,下面這篇文章主要給大家介紹了關(guān)于vue3+vite自定義封裝vue組件發(fā)布到npm包的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • 詳解vue-cli 構(gòu)建項目 vue-cli請求后臺接口 vue-cli使用axios、sass、swiper

    詳解vue-cli 構(gòu)建項目 vue-cli請求后臺接口 vue-cli使用axios、sass、swiper

    本文通過實例代碼給大家詳細介紹了vue-cli 構(gòu)建項目 vue-cli請求后臺接口 vue-cli使用axios、sass、swiper的相關(guān)知識,需要的朋友可以參考下
    2018-05-05

最新評論

思茅市| 信宜市| 杭锦后旗| 临泉县| 华阴市| 新疆| 广汉市| 翼城县| 延吉市| 安多县| 定日县| 怀化市| 廉江市| 东平县| 五指山市| 桂东县| 溧水县| 高阳县| 喀喇| 县级市| 清原| 许昌县| 安乡县| 景德镇市| 城市| 西充县| 读书| 恩平市| 富蕴县| 海安县| 攀枝花市| 榆树市| 安阳市| 都兰县| 新丰县| 嘉峪关市| 建瓯市| 张家界市| 高雄县| 大同市| 镇江市|