目錄
目錄X
Vue動(dòng)態(tài)路由主要場(chǎng)景
在 Vue 中實(shí)現(xiàn)動(dòng)態(tài)路由主要有兩種場(chǎng)景:基于用戶權(quán)限動(dòng)態(tài)生成路由表和基于路由參數(shù)動(dòng)態(tài)渲染組件。下面我將分別介紹這兩種場(chǎng)景的實(shí)現(xiàn)方法。
場(chǎng)景 1:基于用戶權(quán)限動(dòng)態(tài)生成路由表
這種場(chǎng)景適用于不同用戶角色訪問(wèn)不同頁(yè)面的情況。核心思路是:
步驟示例:
定義基礎(chǔ)路由和異步路由
// router.js import VueRouter from 'vue-router' // 基礎(chǔ)路由(所有用戶都能訪問(wèn)) export const constantRoutes = [ { path: '/login', component: Login }, { path: '/404', component: NotFound } ] // 異步路由(需要權(quán)限控制) export const asyncRoutes = [ { path: '/admin', component: Layout, meta: { roles: ['admin'] }, children: [{ path: 'dashboard', component: Dashboard }] }, { path: '/user', component: Layout, meta: { roles: ['user', 'admin'] }, children: [{ path: 'profile', component: Profile }] } ] const router = new VueRouter({ routes: constantRoutes }) export default router
權(quán)限校驗(yàn)與動(dòng)態(tài)添加路由
// permission.js(路由守衛(wèi)) import router from './router' import { asyncRoutes } from './router' router.beforeEach(async (to, from, next) => { const hasToken = localStorage.getItem('token') if (hasToken) { if (to.path === '/login') { next('/') } else { const hasRoles = store.getters.roles && store.getters.roles.length > 0 if (hasRoles) { next() } else { try { // 獲取用戶角色 const { roles } = await store.dispatch('user/getInfo') // 根據(jù)角色過(guò)濾路由 const accessRoutes = filterAsyncRoutes(asyncRoutes, roles) // 動(dòng)態(tài)添加路由 accessRoutes.forEach(route => { router.addRoute(route) }) // 確保路由添加完成 next({ ...to, replace: true }) } catch (error) { next('/login') } } } } else { next('/login') } }) // 過(guò)濾路由的工具函數(shù) function filterAsyncRoutes(routes, roles) { const res = [] routes.forEach(route => { const tmp = { ...route } if (hasPermission(roles, tmp.meta?.roles)) { if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, roles) } res.push(tmp) } }) return res } function hasPermission(roles, routeRoles) { if (!routeRoles) return true return roles.some(role => routeRoles.includes(role)) }
場(chǎng)景 2:基于路由參數(shù)動(dòng)態(tài)渲染組件
這種場(chǎng)景適用于同一個(gè)路由路徑根據(jù)不同參數(shù)渲染不同內(nèi)容的情況。核心思路是:
步驟示例:
定義動(dòng)態(tài)路由
// router.js { path: '/article/:id', name: 'Article', component: Article }
在組件內(nèi)根據(jù)參數(shù)加載數(shù)據(jù)
<!-- Article.vue --> <template> <div> <h1>{{ article.title }}</h1> <p>{{ article.content }}</p> </div> </template> <script> export default { data() { return { article: {} } }, created() { this.fetchArticle() }, watch: { // 監(jiān)聽(tīng)路由參數(shù)變化,避免相同組件實(shí)例復(fù)用導(dǎo)致數(shù)據(jù)不更新 '$route.params.id': { immediate: true, handler() { this.fetchArticle() } } }, methods: { async fetchArticle() { try { const res = await axios.get(`/api/articles/${this.$route.params.id}`) this.article = res.data } catch (error) { console.error(error) } } } } </script>