1. 初识Vue 3路由双雄useRouter与useRoute刚接触Vue 3的路由系统时我经常把useRouter和useRoute这两个家伙搞混。直到有次在项目里踩了坑才明白它们虽然名字相似但分工明确得像咖啡机的两个按钮——一个负责出咖啡路由跳转一个显示当前咖啡种类路由信息。先来个快速区分useRouter是你的导航遥控器能控制页面跳转、前进后退useRoute是当前页面的信息显示屏能读取网址参数、查询字符串等在Options API时代我们要用this.$router和this.$route来操作路由。现在用Composition API直接在setup函数里调用这两个钩子就行代码更干净。我实测过改用这种写法后路由相关代码量减少了约30%特别是复用逻辑时特别爽。2. useRouter的五大实战技巧2.1 智能跳转的三种姿势最基础的跳转大家都会用router.push(/home)但实际项目中我推荐这些更聪明的写法// 命名路由参数最推荐 router.push({ name: userProfile, params: { id: 123 }, query: { from: dashboard } }) // 带hash跳转 router.push(/docs#installation) // 替换当前历史记录适合登录后跳转 router.replace(/dashboard)踩坑提醒params在命名路由中才能生效如果是普通路径路由得用query传参。有次我调试半天才发现这个问题血泪教训啊2.2 历史记录操控秘籍做后台管理系统时经常需要定制返回逻辑。比如这个场景从详情页返回时要记住之前的筛选条件。// 返回两步并刷新 router.go(-2) location.reload() // 高级用法监听路由变化 const unwatch router.afterEach((to, from) { if (from.path /checkout) { showThankYouModal() } }) // 组件卸载时记得取消监听 onUnmounted(() unwatch())2.3 路由拦截的黄金组合配合导航守卫使用能实现精细化的权限控制。这是我的常用套路router.beforeEach((to, from, next) { if (to.meta.requiresAuth !store.state.user) { next({ path: /login, query: { redirect: to.fullPath } }) } else { next() } })在组件内还可以用router.hasRoute()动态检查路由是否存在避免跳转到不存在的页面。3. useRoute的高阶玩法3.1 动态参数处理最佳实践处理动态路由参数时新手常犯的错误是直接使用route.params.id。更健壮的写法应该是import { computed } from vue const userId computed(() { const id Number(route.params.id) return isNaN(id) ? 0 : id })如果参数可能不存在建议加上类型检查和默认值const category computed(() route.params.category || default)3.2 查询参数自动化监听搜索页面经常需要根据query参数重新获取数据。手动监听太麻烦试试这个自动响应方案watch( () route.query, (newQuery) { fetchResults(newQuery) }, { immediate: true } )对于分页参数我习惯封装成计算属性const pageInfo computed(() ({ page: Number(route.query.page) || 1, size: Number(route.query.size) || 10 }))3.3 路由元信息妙用在路由配置里定义meta字段可以实现很多神奇功能{ path: /admin, meta: { requiresAuth: true, transition: slide-left } }组件内读取元信息const transitionName computed(() route.meta.transition || fade)4. 组合使用的高级模式4.1 路由状态共享方案多个组件需要共用路由信息时可以提取成共享hook// hooks/useRouteInfo.js export function useRouteInfo() { const route useRoute() const isActive (path) route.path.startsWith(path) return { currentPath: computed(() route.path), isActive } }4.2 动态路由权限方案配合后端接口实现动态路由加载const router createRouter({ /* 基础路由 */ }) // 登录后加载权限路由 async function loadRoutes() { const menus await fetchUserMenus() menus.forEach(menu { router.addRoute({ path: menu.path, component: () import(/views/${menu.component}) }) }) }4.3 过渡动画联动技巧根据路由变化方向应用不同动画const routeDepth ref(0) watch( () route.path, (newVal, oldVal) { routeDepth.value compareRoutes(newVal, oldVal) } )然后在模板中使用router-view v-slot{ Component } transition :namerouteDepth 0 ? slide-left : slide-right component :isComponent / /transition /router-view5. 性能优化与调试技巧5.1 路由懒加载的现代方案除了常规的() import()Vue 3还支持更高级的懒加载{ path: /dashboard, component: defineAsyncComponent({ loader: () import(./views/Dashboard.vue), delay: 200, // 延迟显示loading的时间 timeout: 3000 // 超时时间 }) }5.2 路由信息持久化用Pinia或localStorage保存路由状态// store/route.js export const useRouteStore defineStore(route, { state: () ({ lastVisited: null }), actions: { updateLastVisited(route) { this.lastVisited route.fullPath } } })5.3 调试神器路由日志开发时添加路由变化监听router.afterEach((to, from) { console.log( [路由跳转] ${from.path} → ${to.path}, 参数变化:, diff(from.params, to.params) ) })对于复杂项目建议安装vue-router的devtools插件能直观查看路由树和状态。