燕郊做网站的公司,网站开发配置,怎么在网上找做网站的客户,招聘网站做沙龙Vue路由深度解析#xff1a;Vue Router与导航守卫
一、Vue Router基础与安装配置
1. Vue Router核心概念
Vue Router是Vue.js官方的路由管理器#xff0c;主要功能包括#xff1a;
嵌套路由映射模块化的路由配置路由参数、查询、通配符细粒度的导航控制自动激活的CSS类链…Vue路由深度解析Vue Router与导航守卫
一、Vue Router基础与安装配置
1. Vue Router核心概念
Vue Router是Vue.js官方的路由管理器主要功能包括
嵌套路由映射模块化的路由配置路由参数、查询、通配符细粒度的导航控制自动激活的CSS类链接HTML5 history模式或hash模式可定制的滚动行为
2. 安装与基本配置
安装Vue Router
npm install vue-router4
# 或
yarn add vue-router4基础配置示例
// router/index.js
import { createRouter, createWebHistory } from vue-router
import HomeView from ../views/HomeView.vueconst routes [{path: /,name: home,component: HomeView},{path: /about,name: about,// 路由级代码拆分component: () import(../views/AboutView.vue)}
]const router createRouter({history: createWebHistory(process.env.BASE_URL),routes
})export default router在main.js中引入
import { createApp } from vue
import App from ./App.vue
import router from ./routerconst app createApp(App)
app.use(router)
app.mount(#app)二、路由模式与路由配置详解
1. 路由模式对比
模式特点示例Hash模式使用URL hash模拟完整URLhttp://example.com/#/aboutHistory模式使用HTML5 History APIhttp://example.com/aboutMemory模式不修改URL适合非浏览器环境(如Electron)无URL变化
配置示例
import { createWebHashHistory, // Hash模式createWebHistory, // History模式createMemoryHistory // Memory模式
} from vue-routerconst router createRouter({history: createWebHistory(), // 推荐生产环境使用// history: createWebHashHistory(), // 兼容性更好// history: createMemoryHistory(), // 非浏览器环境routes
})2. 动态路由与参数传递
动态路由配置
const routes [// 动态字段以冒号开始{path: /user/:id,name: user,component: UserView},// 可匹配/user/123或/user/456{path: /user/:id/posts/:postId,component: UserPostView}
]参数获取方式
template!-- 在模板中直接使用 --div用户ID: {{ $route.params.id }}/div
/templatescript setup
import { useRoute } from vue-router// 在setup中使用
const route useRoute()
console.log(route.params.id)
/scriptscript
// 在Options API中使用
export default {created() {console.log(this.$route.params.id)}
}
/script3. 嵌套路由与命名视图
嵌套路由配置
const routes [{path: /user/:id,component: UserLayout,children: [{path: , // 默认子路由component: UserProfile},{path: posts,component: UserPosts},{path: settings,component: UserSettings}]}
]命名视图(多路由出口)
const routes [{path: /,components: {default: HomeView, // 默认出口sidebar: SidebarView, // router-view namesidebarfooter: AppFooter // router-view namefooter}}
]三、导航守卫全面解析
1. 导航守卫类型与执行流程
完整的导航解析流程
导航被触发调用beforeRouteLeave守卫(组件内)调用全局beforeEach守卫在重用的组件里调用beforeRouteUpdate守卫(组件内)调用路由配置里的beforeEnter守卫解析异步路由组件在被激活的组件里调用beforeRouteEnter(组件内)调用全局beforeResolve守卫导航被确认调用全局afterEach钩子触发DOM更新调用beforeRouteEnter守卫中传给next的回调函数
2. 全局守卫
// router/index.js// 全局前置守卫
router.beforeEach((to, from, next) {console.log(全局前置守卫, to, from)// 必须调用next()继续导航next()
})// 全局解析守卫
router.beforeResolve((to, from, next) {console.log(全局解析守卫, to, from)next()
})// 全局后置钩子
router.afterEach((to, from) {console.log(全局后置钩子, to, from)// 不需要next函数
})3. 路由独享守卫
const routes [{path: /admin,component: AdminView,beforeEnter: (to, from, next) {// 仅在此路由触发if (isAdmin()) next()else next(/login)}}
]4. 组件内守卫
script
export default {beforeRouteEnter(to, from, next) {// 在渲染该组件的对应路由被验证前调用// 不能获取组件实例 thisnext(vm {// 通过 vm 访问组件实例console.log(vm.someData)})},beforeRouteUpdate(to, from) {// 当前路由改变但是该组件被复用时调用// 可以访问组件实例 thisthis.fetchData(to.params.id)},beforeRouteLeave(to, from) {// 导航离开该组件的对应路由时调用// 可以访问组件实例 thisconst answer window.confirm(确定要离开吗未保存的更改将会丢失)if (!answer) return false}
}
/script5. 导航守卫实战权限控制
// router/index.js
import { useAuthStore } from /stores/authconst routes [{path: /,name: home,component: HomeView,meta: { requiresAuth: false }},{path: /dashboard,name: dashboard,component: DashboardView,meta: { requiresAuth: true,roles: [admin, editor] }},{path: /admin,name: admin,component: AdminView,meta: { requiresAuth: true,roles: [admin] }}
]router.beforeEach(async (to, from, next) {const authStore useAuthStore()const isAuthenticated authStore.isAuthenticatedconst userRole authStore.user?.role || guest// 检查路由是否需要认证if (to.meta.requiresAuth !isAuthenticated) {return next({ name: login, query: { redirect: to.fullPath } })}// 检查路由角色权限if (to.meta.roles !to.meta.roles.includes(userRole)) {return next({ name: forbidden })}// 如果用户已登录但要去登录页重定向到首页if (to.name login isAuthenticated) {return next({ name: home })}next()
})四、路由高级特性
1. 路由元信息与过渡动画
路由元信息配置
const routes [{path: /posts,component: PostsLayout,meta: { requiresAuth: true,transition: slide-left },children: [{path: new,component: NewPost,meta: { transition: slide-up,requiresAdmin: true }}]}
]动态过渡效果
templaterouter-view v-slot{ Component, route }transition :nameroute.meta.transition || fadecomponent :isComponent //transition/router-view
/templatestyle
.fade-enter-active,
.fade-leave-active {transition: opacity 0.3s ease;
}.fade-enter-from,
.fade-leave-to {opacity: 0;
}.slide-left-enter-active,
.slide-left-leave-active {transition: transform 0.3s ease;
}.slide-left-enter-from {transform: translateX(100%);
}.slide-left-leave-to {transform: translateX(-100%);
}.slide-up-enter-active,
.slide-up-leave-active {transition: transform 0.3s ease;
}.slide-up-enter-from {transform: translateY(100%);
}.slide-up-leave-to {transform: translateY(-100%);
}
/style2. 滚动行为控制
const router createRouter({history: createWebHistory(),routes,scrollBehavior(to, from, savedPosition) {// 返回滚动位置对象if (savedPosition) {return savedPosition // 浏览器前进/后退时恢复位置}if (to.hash) {return {el: to.hash, // 滚动到锚点behavior: smooth // 平滑滚动}}if (to.meta.scrollToTop) {return { top: 0 } // 新路由滚动到顶部}// 默认不改变滚动位置}
})3. 路由懒加载与分包
基础懒加载
const routes [{path: /about,component: () import(../views/AboutView.vue)}
]自定义分包
const routes [{path: /admin,component: () import(/* webpackChunkName: admin */ ../views/AdminView.vue),children: [{path: dashboard,component: () import(/* webpackChunkName: admin */ ../views/AdminDashboard.vue)}]},{path: /user/:id,component: () import(/* webpackChunkName: user */ ../views/UserView.vue)}
]4. 动态路由API
添加路由
router.addRoute({path: /new-route,name: newRoute,component: () import(../views/NewView.vue)
})// 添加到现有路由的子路由
router.addRoute(parentRoute, {path: child,component: () import(../views/ChildView.vue)
})删除路由
// 通过名称删除
router.removeRoute(routeName)// 通过添加返回的回调删除
const removeRoute router.addRoute(routeConfig)
removeRoute() // 删除路由检查路由
// 检查路由是否存在
router.hasRoute(routeName)// 获取所有路由记录
router.getRoutes()五、常见问题与最佳实践
1. 常见问题解决方案
问题1路由重复跳转报错
// 统一处理导航错误
router.onError((error) {if (error.message.includes(Avoided redundant navigation)) {// 忽略重复导航错误} else {// 处理其他导航错误}
})问题2动态路由刷新404
History模式需要服务器配置支持Nginx配置示例location / {try_files $uri $uri/ /index.html;
}问题3路由组件不更新
// 使用beforeRouteUpdate或监听$route
watch(() route.params.id,(newId) {fetchData(newId)}
)2. 最佳实践建议 路由组织 按功能模块组织路由文件使用路由元信息(meta)存储权限、标题等信息对大型项目考虑自动导入路由 性能优化 合理使用路由懒加载对频繁访问的路由考虑预加载避免在导航守卫中进行繁重操作 安全实践 始终验证前端路由权限敏感路由应在后端再次验证使用路由独享守卫处理特殊权限 开发体验 为路由添加name属性方便跳转使用路由元信息管理页面标题实现进度条提升用户体验
六、综合实战企业级路由方案
1. 完整路由配置示例
// router/index.js
import { createRouter, createWebHistory } from vue-router
import { useAuthStore } from /stores/auth
import NProgress from nprogressconst routes [{path: /,name: home,component: () import(/views/HomeView.vue),meta: {title: 首页,requiresAuth: false,cache: true}},{path: /login,name: login,component: () import(/views/LoginView.vue),meta: {title: 登录,guestOnly: true}},{path: /dashboard,name: dashboard,component: () import(/views/DashboardView.vue),meta: {title: 仪表盘,requiresAuth: true}},{path: /admin,name: admin,component: () import(/views/layouts/AdminLayout.vue),meta: {title: 管理后台,requiresAuth: true,roles: [admin]},children: [{path: ,name: admin-dashboard,component: () import(/views/admin/DashboardView.vue),meta: { title: 控制台 }},{path: users,name: admin-users,component: () import(/views/admin/UsersView.vue),meta: { title: 用户管理 }}]},{path: /:pathMatch(.*)*,name: not-found,component: () import(/views/NotFoundView.vue),meta: {title: 页面不存在}}
]const router createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes,scrollBehavior(to, from, savedPosition) {if (savedPosition) return savedPositionif (to.hash) return { el: to.hash, behavior: smooth }return { top: 0 }}
})// 进度条配置
NProgress.configure({ showSpinner: false })// 全局前置守卫
router.beforeEach(async (to, from, next) {NProgress.start()const authStore useAuthStore()const isAuthenticated authStore.isAuthenticatedconst userRole authStore.user?.role || guest// 设置页面标题document.title to.meta.title ? ${to.meta.title} | 我的应用 : 我的应用// 检查认证if (to.meta.requiresAuth !isAuthenticated) {return next({name: login,query: { redirect: to.fullPath }})}// 检查角色权限if (to.meta.roles !to.meta.roles.includes(userRole)) {return next({ name: forbidden })}// 已登录用户访问guestOnly路由if (to.meta.guestOnly isAuthenticated) {return next({ name: home })}next()
})// 全局后置钩子
router.afterEach(() {NProgress.done()
})export default router2. 路由工具函数
// utils/router.js
export function resetRouter() {const newRouter createRouter()router.matcher newRouter.matcher // 重置路由
}export function loadRoutesByRole(role) {const dynamicRoutes []if (role admin) {dynamicRoutes.push({path: /admin,component: () import(/views/AdminView.vue),children: [// 管理员专属路由]})}dynamicRoutes.forEach(route {router.addRoute(route)})
}export function getRouteTitle(route) {return route.meta.title ||
}3. 路由与状态管理集成
// stores/app.js
import { defineStore } from pinia
import { useRouter } from vue-routerexport const useAppStore defineStore(app, {state: () ({cachedViews: [],visitedViews: []}),actions: {addCachedView(view) {if (this.cachedViews.includes(view.name)) returnif (view.meta?.cache) {this.cachedViews.push(view.name)}},addVisitedView(view) {const existing this.visitedViews.find(v v.path view.path)if (existing) {if (existing.fullPath ! view.fullPath) {// 更新现有记录Object.assign(existing, view)}return}this.visitedViews.push(Object.assign({}, view, {title: view.meta?.title || 未知}))},async logout() {const router useRouter()// 清理状态this.$reset()// 重定向到登录页await router.push(/login)}}
})通过本指南您已经全面掌握了Vue Router的核心概念和高级用法。从基础配置到导航守卫从动态路由到状态集成这些知识将帮助您构建复杂且高效的单页应用程序。实际项目中应根据具体需求选择合适的路由方案并遵循最佳实践以确保应用的性能和可维护性。