Vue动态路由主要场景
在 Vue 中实现动态路由主要有两种场景:基于用户权限动态生成路由表和基于路由参数动态渲染组件。下面我将分别介绍这两种场景的实现方法。
场景 1:基于用户权限动态生成路由表
这种场景适用于不同用户角色访问不同页面的情况。核心思路是:
步骤示例:
定义基础路由和异步路由
// router.js import VueRouter from 'vue-router' // 基础路由(所有用户都能访问) export const constantRoutes = [ { path: '/login', component: Login }, { path: '/404', component: NotFound } ] // 异步路由(需要权限控制) 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
权限校验与动态添加路由
// permission.js(路由守卫) 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') // 根据角色过滤路由 const accessRoutes = filterAsyncRoutes(asyncRoutes, roles) // 动态添加路由 accessRoutes.forEach(route => { router.addRoute(route) }) // 确保路由添加完成 next({ ...to, replace: true }) } catch (error) { next('/login') } } } } else { next('/login') } }) // 过滤路由的工具函数 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)) }
场景 2:基于路由参数动态渲染组件
这种场景适用于同一个路由路径根据不同参数渲染不同内容的情况。核心思路是:
步骤示例:
定义动态路由
// router.js { path: '/article/:id', name: 'Article', component: Article }
在组件内根据参数加载数据
<!-- Article.vue --> <template> <div> <h1>{{ article.title }}</h1> <p>{{ article.content }}</p> </div> </template> <script> export default { data() { return { article: {} } }, created() { this.fetchArticle() }, watch: { // 监听路由参数变化,避免相同组件实例复用导致数据不更新 '$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>
用户登录
还没有账号?
立即注册