方案一:前端全量配置路由表 + 后端返回權限碼
思路
所有可能的路由都在前端
router
中靜態配置好(就像你現在這樣)。登錄后,后端返回當前用戶的菜單權限(通常是一個權限
code
列表)。前端根據權限碼過濾掉無權訪問的路由,生成最終的可訪問菜單。
優點
路由結構清晰,開發時有完整的路由提示和類型支持。
不依賴后端返回路由結構,前端可獨立開發和調試。
性能好,減少一次菜單結構的接口解析。
缺點
每次新增菜單都需要前端改代碼并發版。
如果菜單結構變化頻繁,前端維護成本高。
方案二:后端返回菜單/路由結構,前端動態生成路由
思路
登錄后,后端直接返回當前用戶可訪問的菜單樹(包含
path
、component
、meta
等信息)。前端用
router.addRoute()
動態注冊路由。菜單渲染直接用后端返回的數據。
優點
菜單和權限完全由后端控制,前端無需改代碼即可調整菜單結構。
多端(Web、App、小程序)可共用一套菜單權限數據。
缺點
前端需要做動態組件加載(
import()
),并處理找不到組件的情況。路由類型提示和 IDE 自動補全會缺失。
如果后端返回的路由數據有誤,前端可能直接掛掉。
建議
如果你的系統菜單變化不頻繁(比如 ERP、后臺管理系統),推薦方案一: 前端全量配置路由,后端只返回權限碼,前端過濾展示。 這樣開發體驗好,調試方便,出錯率低。
如果你的系統菜單變化頻繁(比如 SaaS 平臺,不同客戶菜單差異大),推薦方案二: 后端返回菜單樹,前端動態注冊路由,真正做到菜單和權限后端可配。
混合方案(很多企業在用)
前端維護一個路由組件映射表(
path
→component
)。后端返回菜單結構(只包含
path
、meta
等),前端用映射表找到對應組件并動態注冊。這樣既能后端控制菜單,又能保證組件路徑可控。
// 路由組件映射表
const componentMap = {'dashboard': () => import('@/views/Dashboard/index.vue'),'system/user': () => import('@/views/System/User.vue'),// ...
}// 動態注冊
menus.forEach(menu => {router.addRoute('Layout', {path: menu.path,name: menu.name,component: componentMap[menu.component]})
})
方案一和方案二速度上性能比較
性能對比
對比項 | 方案一:前端全量配置 + 權限過濾 | 方案二:后端返回菜單/路由結構 |
---|---|---|
首屏速度 | 較快。路由表已經在打包時編譯進前端代碼,進入系統時只需拿到權限碼做一次本地過濾即可。 | 稍慢。登錄后需要額外請求菜單數據,再根據數據動態注冊路由,才能進入頁面。 |
網絡請求 | 登錄接口 + 權限接口(可合并),不需要額外的菜單結構接口。 | 登錄接口 + 菜單接口(必需),多一次網絡往返。 |
渲染延遲 | 幾乎無延遲,過濾完成即可渲染。 | 需要等菜單接口返回并處理完動態路由后才能渲染。 |
打包體積 | 稍大(包含所有路由組件),但可配合懶加載減少首屏體積。 | 可能稍小(只加載基礎路由),但動態加載組件時會有額外延遲。 |
總結
速度優先 → 方案一更快,因為路由表和組件都已經在前端準備好,進入系統時只做一次本地過濾。
靈活性優先 → 方案二更靈活,菜單結構改動不需要前端發版,但首屏會慢一點。
為什么混合方案比方案二能提升速度那?
組件路徑提前確定,避免運行時查找失敗
方案二:后端返回的
component
通常是字符串(如"system/user"
),前端需要在運行時用import()
去拼接路徑并加載,這個過程會觸發 Webpack 的動態模塊查找,范圍大時會生成一個很大的動態 chunk map,解析和匹配都要時間。混合方案:前端事先維護一個
componentMap
(key → import函數
),直接用componentMap[menu.component]
獲取組件加載函數,跳過了運行時路徑匹配,Webpack 只打包實際用到的模塊,按需加載更快。
路由注冊邏輯更輕量
方案二:后端返回的菜單數據需要先做一輪“數據清洗 + 動態 import + 異步注冊”,這一步必須等接口返回后才能開始。
混合方案:后端只返回菜單結構(不含復雜組件路徑解析),前端拿到數據后直接用映射表匹配組件并注冊,省去了動態路徑解析的耗時。
首屏渲染提前啟動
方案二:首屏必須等菜單接口返回 + 動態 import 完成后才能渲染主框架。
混合方案:因為組件映射表在打包時就存在,首屏可以先渲染 Layout 框架,菜單接口返回后再補充路由,不會阻塞主框架渲染。
打包優化更好
方案二:動態路徑 import 可能導致 Webpack 打包出一個大而全的 chunk(因為它無法靜態分析具體會用到哪些組件)。
混合方案:映射表是靜態的,Webpack 能精確分割 chunk,按需加載,減少首屏下載體積。
總結
混合方案的提速點在于:
路徑解析提前到編譯期,減少運行時動態匹配
組件按需打包,避免大 chunk
首屏可并行渲染,減少等待時間