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

Vue實現(xiàn)動態(tài)路由設(shè)置的兩大方法詳解

 更新時間:2026年04月14日 09:45:22   作者:蠟臺  
這篇文章主要為大家詳細介紹了Vue中兩種動態(tài)路由設(shè)置方案,主要是前端控制方案和后端控制方案,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

動態(tài)路由設(shè)置一般有兩種:

一、簡單的角色路由設(shè)置(前端控制)‌

這種方式適用于角色較少且權(quán)限相對固定的場景。前端預(yù)先定義好所有可能的路由和對應(yīng)的角色權(quán)限,然后根據(jù)用戶登錄時獲取的角色信息來篩選出用戶可訪問的路由。

代碼實現(xiàn):

1‌、路由配置文件 (router/index.js)‌:定義靜態(tài)路由和異步路由(權(quán)限路由)。

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Layout from '@/layout'
    import store from '@/store' // 假設(shè)使用 Vuex 存儲用戶角色

    Vue.use(VueRouter)

    // 靜態(tài)路由,無需權(quán)限即可訪問
    export const constantRoutes = [
      {
        path: '/login',
        component: () => import('@/views/login'),
        hidden: true
      },
      {
        path: '/404',
        component: () => import('@/views/404'),
        hidden: true
      }
    ]

    // 異步路由,根據(jù)角色權(quán)限加載
    export const asyncRoutes = [
      {
        path: '/permission',
        component: Layout,
        redirect: '/permission/page',
        alwaysShow: true,
        name: 'Permission',
        meta: {
          title: '權(quán)限管理',
          roles: ['admin', 'editor'] // 普通的用戶角色
        },
        children: [
          {
            path: 'page',
            component: () => import('@/views/permission/page'),
            name: 'PagePermission',
            meta: {
              title: '頁面權(quán)限',
              roles: ['editor'] // editor角色的用戶才能訪問該頁面
            }
          },
          {
            path: 'role',
            component: () => import('@/views/permission/role'),
            name: 'RolePermission',
            meta: {
              title: '角色權(quán)限',
              roles: ['admin'] // admin角色的用戶才能訪問該頁面
            }
          }
        ]
      },
      {
        path: '/dashboard',
        component: Layout,
        name: 'Dashboard',
        meta: {
          title: '儀表盤',
          roles: ['admin', 'user'] // admin 和 user 都可以訪問
        }
      }
      // 可以繼續(xù)添加更多異步路由...
    ]

    const createRouter = () => new VueRouter({
      mode: 'history',
      scrollBehavior: () => ({ y: 0 }),
      routes: constantRoutes
    })

    const router = createRouter()

    // 用于重置路由的方法(例如用戶登出后)
    export function resetRouter() {
      const newRouter = createRouter()
      router.matcher = newRouter.matcher // 重置路由匹配器
    }

    export default router
    

2‌、權(quán)限過濾工具 (utils/asyncRouter.js)‌:根據(jù)用戶角色過濾異步路由。

    /**
     * 判斷當(dāng)前用戶是否有訪問該路由的權(quán)限
     * @param {Array} roles - 用戶的角色列表
     * @param {Object} route - 路由對象
     * @returns {Boolean}
     */
    export function hasPermission(roles, route) {
      if (route.meta && route.meta.roles) {
        // 如果路由定義了需要的角色,則檢查用戶角色是否包含在內(nèi)
        return roles.some(role => route.meta.roles.includes(role))
      } else {
        // 如果沒有定義角色,則默認允許訪問
        return true
      }
    }

    /**
     * 遞歸過濾異步路由表,篩選出用戶有權(quán)限訪問的路由
     * @param {Array} routes - 異步路由列表
     * @param {Array} roles - 用戶的角色列表
     * @returns {Array}
     */
    export function filterAsyncRoutes(routes, roles) {
      const res = []
      routes.forEach(route => {
        const tmp = { ...route }
        if (hasPermission(roles, tmp)) {
          // 如果有子路由,遞歸過濾子路由
          if (tmp.children) {
            tmp.children = filterAsyncRoutes(tmp.children, roles)
          }
          res.push(tmp)
        }
      })
      return res
    }
    

‌3、路由守衛(wèi) (permission.js)‌:在路由跳轉(zhuǎn)前進行權(quán)限判斷。

    import router from './router'
    import store from './store'
    import { getToken } from '@/utils/auth' // 假設(shè)有一個獲取 token 的工具函數(shù)
    import { filterAsyncRoutes } from '@/utils/asyncRouter' // 引入權(quán)限過濾工具
    import NProgress from 'nprogress' // 進度條
    import 'nprogress/nprogress.css'

    NProgress.configure({ showSpinner: false })

    const whiteList = ['/login'] // 白名單,不需要登錄即可訪問的路由

    router.beforeEach(async (to, from, next) => {
      // 開始進度條
      NProgress.start()

      // 獲取 token
      const token = getToken()

      if (token) {
        // 如果已經(jīng)登錄
        if (to.path === '/login') {
          // 如果訪問的是登錄頁,則跳轉(zhuǎn)到首頁
          next({ path: '/' })
          NProgress.done()
        } else {
          // 檢查用戶信息是否已獲取
          const hasRoles = store.getters.roles && store.getters.roles.length > 0
          if (hasRoles) {
            // 如果用戶角色已存在,則直接進入
            next()
          } else {
            try {
              // 獲取用戶信息(通常包含角色)
              const { roles } = await store.dispatch('user/getUserInfo')
              // 根據(jù)用戶角色過濾路由
              const accessRoutes = filterAsyncRoutes(asyncRoutes, roles)
              // 動態(tài)添加路由
              router.addRoutes(accessRoutes)
              // 將過濾后的路由存入 store(可選,用于菜單渲染等)
              store.commit('permission/SET_ROUTES', accessRoutes)
              // 繼續(xù)導(dǎo)航
              next({ ...to, replace: true })
            } catch (error) {
              // 獲取用戶信息失敗,清除 token 并跳轉(zhuǎn)到登錄頁
              await store.dispatch('user/resetToken')
              next(`/login?redirect=${to.path}`)
              NProgress.done()
            }
          }
        }
      } else {
        // 如果未登錄
        if (whiteList.indexOf(to.path) !== -1) {
          // 如果是白名單中的路由,則直接進入
          next()
        } else {
          // 否則跳轉(zhuǎn)到登錄頁
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    })

    // 路由結(jié)束
    router.afterEach(() => {
      NProgress.done()
    })
    

二、復(fù)雜的路由權(quán)限設(shè)置(后端控制)‌

這種方式適用于權(quán)限復(fù)雜、角色多變的系統(tǒng)。前端不預(yù)先定義所有路由,而是由后端返回用戶當(dāng)前擁有的路由列表,前端根據(jù)這個列表動態(tài)添加路由。

代碼實現(xiàn):

‌1、路由配置文件 (router/index.js)‌:只定義靜態(tài)路由和一個空的動態(tài)路由數(shù)組

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Layout from '@/layout'
    import store from '@/store'

    Vue.use(VueRouter)

    // 靜態(tài)路由,無需權(quán)限即可訪問
    export const constantRoutes = [
      {
        path: '/login',
        component: () => import('@/views/login'),
        hidden: true
      },
      {
        path: '/404',
        component: () => import('@/views/404'),
        hidden: true
      }
    ]

    // 動態(tài)路由,由后端返回
    export const asyncRoutes = []

    const createRouter = () => new VueRouter({
      mode: 'history',
      scrollBehavior: () => ({ y: 0 }),
      routes: constantRoutes
    })

    const router = createRouter()

    export function resetRouter() {
      const newRouter = createRouter()
      router.matcher = newRouter.matcher
    }

    export default router
    

2‌、API 請求工具 (api/user.js)‌:用于獲取用戶權(quán)限路由列表。

    import request from '@/utils/request'

    // 獲取用戶信息(包含角色)
    export function getUserInfo() {
      return request({
        url: '/user/info',
        method: 'get'
      })
    }

    // 獲取用戶權(quán)限路由列表(后端返回)
    export function getPermissionRoutes() {
      return request({
        url: '/user/permission/routes',
        method: 'get'
      })
    }
    

3、路由守衛(wèi) (permission.js)‌:在用戶登錄后,調(diào)用后端接口獲取路由列表并動態(tài)添加。

    import router from './router'
    import store from './store'
    import { getToken } from '@/utils/auth'
    import { getPermissionRoutes } from '@/api/user' // 引入獲取權(quán)限路由的 API
    import NProgress from 'nprogress'
    import 'nprogress/nprogress.css'

    NProgress.configure({ showSpinner: false })

    const whiteList = ['/login']

    router.beforeEach(async (to, from, next) => {
      NProgress.start()

      const token = getToken()

      if (token) {
        if (to.path === '/login') {
          next({ path: '/' })
          NProgress.done()
        } else {
          const hasRoles = store.getters.roles && store.getters.roles.length > 0
          if (hasRoles) {
            next()
          } else {
            try {
              // 獲取用戶信息(通常包含角色)
              const { roles } = await store.dispatch('user/getUserInfo')
              // 獲取后端返回的權(quán)限路由列表
              const routeData = await getPermissionRoutes()
              // 假設(shè)后端返回的路由數(shù)據(jù)結(jié)構(gòu)是 { routes: [...], ... }
              const accessRoutes = routeData.routes || []
              // 動態(tài)添加路由
              router.addRoutes(accessRoutes)
              // 將過濾后的路由存入 store(可選,用于菜單渲染等)
              store.commit('permission/SET_ROUTES', accessRoutes)
              next({ ...to, replace: true })
            } catch (error) {
              await store.dispatch('user/resetToken')
              next(`/login?redirect=${to.path}`)
              NProgress.done()
            }
          }
        }
      } else {
        if (whiteList.indexOf(to.path) !== -1) {
          next()
        } else {
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    })

    router.afterEach(() => {
      NProgress.done()
    })
    

三、總結(jié)說明

前端控制):通過在路由配置中定義 meta.roles 字段來標記路由所需的角色。在路由守衛(wèi)中,根據(jù)用戶角色調(diào)用 filterAsyncRoutes 函數(shù)過濾出用戶可訪問的路由,并使用 router.addRoutes 動態(tài)添加。這種方式簡單直接,適合權(quán)限結(jié)構(gòu)相對固定的場景。

后端控制:前端不預(yù)先定義路由,而是通過調(diào)用后端 API 獲取用戶權(quán)限對應(yīng)的路由列表。后端根據(jù)用戶角色和權(quán)限規(guī)則生成路由配置(通常包含 path, component, meta 等信息),前端接收到后直接使用 router.addRoutes 添加。這種方式更靈活,適合權(quán)限復(fù)雜、需要頻繁調(diào)整的系統(tǒng),但需要后端配合提供路由數(shù)據(jù)接口。

兩種方式的核心都是利用 router.addRoutes (Vue Router 3.x) 或 router.addRoute (Vue Router 4.x) 來動態(tài)添加路由,并結(jié)合路由守衛(wèi)進行權(quán)限判斷

注意:vue是單頁面應(yīng)用程序,所以頁面一刷新數(shù)據(jù)部分數(shù)據(jù)也會跟著丟失,所以我們需要將store中的數(shù)據(jù)存儲到本地,才能保證路由不丟失

到此這篇關(guān)于Vue實現(xiàn)動態(tài)路由設(shè)置的兩大方法詳解的文章就介紹到這了,更多相關(guān)Vue動態(tài)路由設(shè)置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

建始县| 镇巴县| 沙洋县| 丁青县| 谢通门县| 梓潼县| 沙坪坝区| 永嘉县| 海原县| 天台县| 湖北省| 安顺市| 岗巴县| 开江县| 得荣县| 大田县| 沈阳市| 南城县| 阿拉善盟| 临高县| 瑞丽市| 广南县| 即墨市| 鱼台县| 英超| 民勤县| 济南市| 江川县| 来宾市| 甘德县| 四子王旗| 桐梓县| 汕头市| 衡阳市| 和龙市| 宜昌市| 裕民县| 彰化市| 二连浩特市| 富民县| 聊城市|