vuerouter路由跳轉,Vue Router 4 動態添加路由詳解
服務端的數據
思考一下,前端在實現動態菜單的時候,服務端會返回什么樣的數據?
創建一個菜單的時候,最基本的是不是得有一個id、標題、路由、組件、父菜單,至于可訪問的權限,暫不考慮。
假設服務端給前端返回了一個樹形結構的數據(其實大多數時候,服務端都是把數據一股腦丟給前端處理的,這里為了方便說明問題,處理成樹形結構)
// 服務端返回的數據// 一般這個數據是存放在store中const menus = [ { id: 0, pid: 0, name: '', title: '初始化', path: '', component: '', children: [{ id: 2, pid: 0, title: '安裝與配置', name: 'home.install', path: 'install', component: 'views/install/Install' }] }, { id: 1, pid: 0, title: '基礎知識', name: '', path: '', component: '', children: [{ id: 3, pid: 1, title: '路由嵌套', name: 'home.nesting', path: 'nesting', component: 'views/nesting/Nesting' }] }]
服務端數據轉路由記錄
需要將服務端返回的數據轉成標準路由地址
/** * 將菜單數據轉化成路由記錄 * @param data 菜單數據 * @param parent * @return 路由記錄數組 **/function transRoute(data) { // 路由記錄數組 const routes = [] data.forEach(v => { // 判斷路由地址是否存在 if(v.path !== '') { // vite下動態加載組件方式 const modules = import.meta.glob('../views/**/*.vue') // 路由記錄對象 const route = {} route.name = v.name route.path = v.path // 這里會被解析成() => import('/src/views/xx/xx.vue') route.component = modules[`../${v.component}.vue`] routes.push(route) } // 如果菜單數據存在子節點children if(v.children && v.children.length) { transRoute(v.children) } }) return routes }
將路由記錄數據動態掛載到router實例
/** * 動態添加路由 * @param routes 路由記錄數組 * @param router router實例 **/export const addRouteDynamically = (routes, router) => { // 獲取已掛載的routes路由記錄, // 找到對應的靜態路由, // 將對應的子路由動態添加到該靜態路由 // 最后掛載到router實例 const _routes = router.options.routes _routes[1].children = [ ..._routes[1].children, ...routes ] router.addRoute(_routes[1]) }
解決瀏覽器刷新導致動態路由消失的問題
思路是,判斷當前路由(to對應的路由地址)是否存在,不存在,則重新添加