Vue Router中useRouter和useRoute的区别与记忆技巧useRouter用于控制路由跳转push/replace/go等方法相当于路由器工具useRoute用于获取当前路由信息params/query/path等相当于路由数据。记忆口诀Router跳转Route参数。核心区分useRouter返回Router实例用于导航操作useRoute返回Route对象包含当前路由信息类比Router是导航系统控制器Route是路况信息数据常见错误混淆变量名router/route在setup外部使用解构失去响应性参数对比params路径参数/user/123必须定义在路由配置中query查询参数?id123无需预定义支持多值useRouter vs useRoute 记忆技巧这是一个非常常见的混淆点useRouteuseRouter1. 快速对比表维度useRouteruseRoute含义路由器实例当前路由信息返回对象Router 对象Route 对象主要用途路由跳转、导航获取路由参数、查询参数常用方法/属性push(),replace(),go(),back(),currentRouteparams,query,path,name,meta,fullPath类比导航系统控制器当前路况信息数据记忆口诀Router 是工具Route 是数据2. 核心记忆方法方法一词源记忆法// Router 路由器工具 // - 用于控制路由跳转、前进、后退 // - 类比物理路由器控制网络数据流向 // Route 路由信息 // - 用于获取信息参数、查询字符串、路径 // - 类比路线信息告诉你当前在哪里方法二首字母记忆法R - Router - 控制 (Control) R - Route - 数据 (Data) 记住Router 是动作Route 是状态方法三英文含义记忆// Router 路由器名词-设备 // - 你在路由器上执行操作 useRouter().push() // 操作路由器 useRouter().back() // 操作路由器 // Route 路线名词-信息 // - 你获取路线上的信息 useRoute().params // 获取路线参数 useRoute().query // 获取路线查询参数3. 使用场景对比script setup import { useRouter, useRoute } from vue-router // ✅ 正确用法 const router useRouter() // 用于跳转 const route useRoute() // 用于获取参数 // 使用场景 1: 路由跳转 function goToDetail() { // 使用 router工具 router.push(/detail) router.push({ name: Detail, params: { id: 1 } }) router.replace(/home) router.back() router.go(-1) } // 使用场景 2: 获取参数 function getRouteInfo() { // 使用 route数据 console.log(route.params.id) // 路由参数 console.log(route.query.keyword) // 查询参数 console.log(route.path) // 当前路径 console.log(route.name) // 路由名称 console.log(route.meta.title) // 元信息 } // 使用场景 3: 组合使用 function handleNavigation() { // 获取当前路由信息route const currentId route.params.id // 使用路由器跳转router router.push(/detail/${currentId}/edit) } /script4. 形象化记忆把路由比作公交车系统// useRouter 公交车调度中心 // - 可以控制车辆发车、返回、调度 const router useRouter() router.push(/home) // 发车去 home router.back() // 车辆返回 router.replace(/login) // 更换目的地 // useRoute 公交车上的信息牌 // - 告诉你当前位置、路线信息 const route useRoute() route.path // 当前在哪条路 route.params // 车上乘客信息 route.query // 路况信息5. 示例在 watch 中监听路由变化import { useRoute } from vue-router import { watch } from vue // ✅ 正确监听 route 的变化 const route useRoute() watch(() route.params.id, (newId) { console.log(路由参数变化, newId) })6. 代码模板记忆法script setup // 固定模板永远记住这个顺序 import { useRouter, useRoute } from vue-router // 1. Router 做操作动词 const router useRouter() // 2. Route 取数据名词 const route useRoute() // 3. 使用时的区分 // 要做什么 → 用 router // 要读什么 → 用 route // 实际应用 function submit() { // 读取当前路由信息读 const userId route.params.id // 执行跳转做 router.push(/user/${userId}/profile) } /script7. 记忆口诀口诀一中文textRouter 跳转Route 参数 想要跳转找 Router 想要参数找 Route口诀二英文textRouter for action (push, go, back) Route for information (params, query, path)8. 属性/方法速查表需求使用对象代码示例页面跳转routerrouter.push(/path)返回上一页routerrouter.back()前进/后退routerrouter.go(-1)替换路由routerrouter.replace(/path)获取 URL 参数routeroute.params.id获取查询参数routeroute.query.page获取当前路径routeroute.path获取路由名称routeroute.name获取路由元信息routeroute.meta.title监听路由变化routewatch(() route.params)获取完整 URLrouteroute.fullPath获取路由哈希routeroute.hash9. 常见错误及纠正// ❌ 错误 1: 混淆变量名 // ✅ 纠正变量名和方法名保持一致 const router useRouter() // router 对应 useRouter const route useRoute() // route 对应 useRoute // ❌ 错误 2: 在组件外使用在 setup 外部或普通函数中 // ✅ 纠正只能在 setup 或组合式函数中调用 function useCustomHook() { const route useRoute() // 在组合式函数中可以 return { id: route.params.id } } // ❌ 错误 3: 解构失去响应性 // ✅ 纠正保持响应性 const route useRoute() const id computed(() route.params.id)useRoute 常用属性params vs query 完整对比Vue Router 中route.params.id 和 route.query.id 的区别URLSearchParams 处理 URL 查询参数的接口params参数参数个数param 的复数queryn. 疑问询问问号; v. 质疑对……表示疑问询问提问对比维度paramsquery定义路由参数路径参数查询参数URL 参数位置在 URL 路径中在 URL 问号?后面URL 示例/user/123/profile/user/profile?id123定义方式路由配置中定义:param无需预定义直接使用路由配置path: /user/:id/profilepath: /user/profile必须性必须在路由规则中定义可选无需预定义刷新页面✅ 参数保留✅ 参数保留编程式导航router.push({ name: user, params: { id: 123 } })router.push({ path: /user, query: { id: 123 } })使用 name 导航✅ 必须配合name使用✅ 可配合path或name使用 path 导航❌ 不能使用 params✅ 可以使用 queryURL 编码自动编码自动编码嵌套路由支持多层嵌套不涉及嵌套关系SEO 友好度较高路径包含关键词一般参数在查询字符串数据类型字符串字符串或数组重复参数典型用途资源 ID、唯一标识符筛选、分页、搜索关键词详细说明与代码示例1. 定义方式对比// 路由配置 const routes [ { // params: 在路径中定义 path: /user/:id/profile, name: user-profile, component: UserProfile }, { // query: 路径中不定义参数 path: /user/profile, name: user-profile-query, component: UserProfile } ]2. URL 格式对比// params 格式 URL: /user/123/profile // params 对象: { id: 123 } // query 格式 URL: /user/profile?id123page1sortdesc // query 对象: { id: 123, page: 1, sort: desc }3. 编程式导航对比script setup import { useRouter } from vue-router const router useRouter() // params 导航 // ✅ 正确必须使用 name router.push({ name: user-profile, params: { id: 123 } }) // 结果: /user/123/profile // ❌ 错误path params 不生效 router.push({ path: /user/profile, params: { id: 123 } // 会被忽略 }) // 结果: /user/profile (参数丢失) // query 导航 // ✅ 方式1: 使用 path query router.push({ path: /user/profile, query: { id: 123, page: 1 } }) // 结果: /user/profile?id123page1 // ✅ 方式2: 使用 name query router.push({ name: user-profile-query, query: { id: 123, page: 1 } }) // 结果: /user/profile?id123page1 /script4. 获取参数对比script setup import { useRoute } from vue-router const route useRoute() // params 获取 // URL: /user/123/profile console.log(route.params.id) // 123 console.log(route.params) // { id: 123 } // query 获取 // URL: /user/profile?id123page1tagsvuetagsrouter console.log(route.query.id) // 123 console.log(route.query.page) // 1 console.log(route.query.tags) // [vue, router] (重复参数转为数组) console.log(route.query) // { id: 123, page: 1, tags: [vue, router] } /script5. 嵌套路由对比// 路由配置 const routes [ { path: /user/:userId, component: UserLayout, children: [ { // params 支持嵌套 path: profile/:profileId, name: user-profile, component: UserProfile }, { // query 不受嵌套影响 path: settings, name: user-settings, component: UserSettings } ] } ] // params 嵌套访问 // URL: /user/123/profile/456 // route.params: { userId: 123, profileId: 456 } // query 在任何层级都可以 // URL: /user/123/settings?tabaccountnotifytrue // route.query: { tab: account, notify: true }6. 刷新页面行为对比script setup import { useRoute } from vue-router const route useRoute() // 页面刷新后 // URL: /user/123/profile // ✅ params 仍然存在 console.log(route.params.id) // 123 // URL: /user/profile?id123 // ✅ query 仍然存在 console.log(route.query.id) // 123 // 两者刷新后都不会丢失 /script7. 数据类型处理script setup import { useRoute } from vue-router const route useRoute() // params 始终是字符串 // URL: /user/123/profile const userId route.params.id // 123 (字符串) const numericId Number(route.params.id) // 需要手动转换 // query 支持多值 // URL: /list?tagsvuetagsreacttagsangular const tags route.query.tags // [vue, react, angular] (数组) // 单个值的情况 // URL: /list?page1 const page route.query.page // 1 (字符串) // 参数不存在时 const sort route.query.sort // undefined /script8. 实际应用场景template div !-- params 场景用户详情页 -- div v-ifroute.params.id h1用户详情/h1 p用户ID: {{ route.params.id }}/p button clickfetchUser(route.params.id) 加载用户 /button /div !-- query 场景商品列表页 -- div h1商品列表/h1 !-- 筛选条件 -- select v-modelfilters.category option valueelectronics电子产品/option option valueclothing服装/option /select input v-modelfilters.keyword placeholder搜索 / !-- 分页 -- div classpagination button clickchangePage(currentPage - 1)上一页/button span第 {{ currentPage }} 页/span button clickchangePage(currentPage 1)下一页/button /div !-- 排序 -- button clickchangeSort(price)按价格排序/button /div /div /template script setup import { useRoute, useRouter } from vue-router import { reactive, watch } from vue const route useRoute() const router useRouter() // params 场景获取用户ID const userId route.params.id // 资源标识符 // query 场景获取筛选条件 const filters reactive({ category: route.query.category || all, keyword: route.query.keyword || , page: Number(route.query.page) || 1, sort: route.query.sort || default }) // 监听筛选条件变化更新 URL query watch(filters, () { router.push({ path: /products, query: { category: filters.category, keyword: filters.keyword, page: filters.page, sort: filters.sort } }) }, { deep: true }) // 翻页函数 function changePage(page) { if (page 1) return filters.page page router.push({ path: /products, query: { ...route.query, page } }) } // 排序函数 function changeSort(sortBy) { filters.sort sortBy router.push({ path: /products, query: { ...route.query, sort: sortBy } }) } /script9. 使用场景选择指南场景推荐使用原因用户详情页paramsID 是资源的唯一标识在路径中更语义化文章详情页params/article/123比/article?id123更美观搜索关键词query可选参数适合/search?qvue分页参数query/list?page2符合 RESTful 规范筛选条件query多条件组合可选且可分享链接排序参数query可选参数不影响路由结构多选框值query支持数组如?tagsvuetagsreactTab 切换query或params如果 Tab 是资源的一部分用 params否则用 query10. 完整示例电商列表页script setup import { useRoute, useRouter } from vue-router import { ref, watch } from vue const route useRoute() const router useRouter() // 获取参数 // URL: /products/category/electronics?page2sortpricebrandapplebrandsamsung // params: 类别标识 const category route.params.category // electronics // query: 筛选条件 const page Number(route.query.page) || 1 const sort route.query.sort || default const brands route.query.brand || [] // [apple, samsung] // 构建筛选器 const filters ref({ page, sort, brands: Array.isArray(brands) ? brands : [brands] }) // 更新 URL function updateFilters() { router.push({ name: products-category, params: { category: category }, query: { page: filters.value.page, sort: filters.value.sort, brand: filters.value.brands } }) } // 监听筛选变化 watch(filters, updateFilters, { deep: true }) /script template div h1分类{{ category }}/h1 div classfilters select v-modelfilters.sort option valuedefault默认排序/option option valueprice价格排序/option option valuesales销量排序/option /select div classbrands label input typecheckbox valueapple v-modelfilters.brands Apple /label label input typecheckbox valuesamsung v-modelfilters.brands Samsung /label /div div classpagination button clickfilters.page--上一页/button span第 {{ filters.page }} 页/span button clickfilters.page下一页/button /div /div /div /template
路由器实例 useRouter,当前路由信息 useRoute(params, query)
Vue Router中useRouter和useRoute的区别与记忆技巧useRouter用于控制路由跳转push/replace/go等方法相当于路由器工具useRoute用于获取当前路由信息params/query/path等相当于路由数据。记忆口诀Router跳转Route参数。核心区分useRouter返回Router实例用于导航操作useRoute返回Route对象包含当前路由信息类比Router是导航系统控制器Route是路况信息数据常见错误混淆变量名router/route在setup外部使用解构失去响应性参数对比params路径参数/user/123必须定义在路由配置中query查询参数?id123无需预定义支持多值useRouter vs useRoute 记忆技巧这是一个非常常见的混淆点useRouteuseRouter1. 快速对比表维度useRouteruseRoute含义路由器实例当前路由信息返回对象Router 对象Route 对象主要用途路由跳转、导航获取路由参数、查询参数常用方法/属性push(),replace(),go(),back(),currentRouteparams,query,path,name,meta,fullPath类比导航系统控制器当前路况信息数据记忆口诀Router 是工具Route 是数据2. 核心记忆方法方法一词源记忆法// Router 路由器工具 // - 用于控制路由跳转、前进、后退 // - 类比物理路由器控制网络数据流向 // Route 路由信息 // - 用于获取信息参数、查询字符串、路径 // - 类比路线信息告诉你当前在哪里方法二首字母记忆法R - Router - 控制 (Control) R - Route - 数据 (Data) 记住Router 是动作Route 是状态方法三英文含义记忆// Router 路由器名词-设备 // - 你在路由器上执行操作 useRouter().push() // 操作路由器 useRouter().back() // 操作路由器 // Route 路线名词-信息 // - 你获取路线上的信息 useRoute().params // 获取路线参数 useRoute().query // 获取路线查询参数3. 使用场景对比script setup import { useRouter, useRoute } from vue-router // ✅ 正确用法 const router useRouter() // 用于跳转 const route useRoute() // 用于获取参数 // 使用场景 1: 路由跳转 function goToDetail() { // 使用 router工具 router.push(/detail) router.push({ name: Detail, params: { id: 1 } }) router.replace(/home) router.back() router.go(-1) } // 使用场景 2: 获取参数 function getRouteInfo() { // 使用 route数据 console.log(route.params.id) // 路由参数 console.log(route.query.keyword) // 查询参数 console.log(route.path) // 当前路径 console.log(route.name) // 路由名称 console.log(route.meta.title) // 元信息 } // 使用场景 3: 组合使用 function handleNavigation() { // 获取当前路由信息route const currentId route.params.id // 使用路由器跳转router router.push(/detail/${currentId}/edit) } /script4. 形象化记忆把路由比作公交车系统// useRouter 公交车调度中心 // - 可以控制车辆发车、返回、调度 const router useRouter() router.push(/home) // 发车去 home router.back() // 车辆返回 router.replace(/login) // 更换目的地 // useRoute 公交车上的信息牌 // - 告诉你当前位置、路线信息 const route useRoute() route.path // 当前在哪条路 route.params // 车上乘客信息 route.query // 路况信息5. 示例在 watch 中监听路由变化import { useRoute } from vue-router import { watch } from vue // ✅ 正确监听 route 的变化 const route useRoute() watch(() route.params.id, (newId) { console.log(路由参数变化, newId) })6. 代码模板记忆法script setup // 固定模板永远记住这个顺序 import { useRouter, useRoute } from vue-router // 1. Router 做操作动词 const router useRouter() // 2. Route 取数据名词 const route useRoute() // 3. 使用时的区分 // 要做什么 → 用 router // 要读什么 → 用 route // 实际应用 function submit() { // 读取当前路由信息读 const userId route.params.id // 执行跳转做 router.push(/user/${userId}/profile) } /script7. 记忆口诀口诀一中文textRouter 跳转Route 参数 想要跳转找 Router 想要参数找 Route口诀二英文textRouter for action (push, go, back) Route for information (params, query, path)8. 属性/方法速查表需求使用对象代码示例页面跳转routerrouter.push(/path)返回上一页routerrouter.back()前进/后退routerrouter.go(-1)替换路由routerrouter.replace(/path)获取 URL 参数routeroute.params.id获取查询参数routeroute.query.page获取当前路径routeroute.path获取路由名称routeroute.name获取路由元信息routeroute.meta.title监听路由变化routewatch(() route.params)获取完整 URLrouteroute.fullPath获取路由哈希routeroute.hash9. 常见错误及纠正// ❌ 错误 1: 混淆变量名 // ✅ 纠正变量名和方法名保持一致 const router useRouter() // router 对应 useRouter const route useRoute() // route 对应 useRoute // ❌ 错误 2: 在组件外使用在 setup 外部或普通函数中 // ✅ 纠正只能在 setup 或组合式函数中调用 function useCustomHook() { const route useRoute() // 在组合式函数中可以 return { id: route.params.id } } // ❌ 错误 3: 解构失去响应性 // ✅ 纠正保持响应性 const route useRoute() const id computed(() route.params.id)useRoute 常用属性params vs query 完整对比Vue Router 中route.params.id 和 route.query.id 的区别URLSearchParams 处理 URL 查询参数的接口params参数参数个数param 的复数queryn. 疑问询问问号; v. 质疑对……表示疑问询问提问对比维度paramsquery定义路由参数路径参数查询参数URL 参数位置在 URL 路径中在 URL 问号?后面URL 示例/user/123/profile/user/profile?id123定义方式路由配置中定义:param无需预定义直接使用路由配置path: /user/:id/profilepath: /user/profile必须性必须在路由规则中定义可选无需预定义刷新页面✅ 参数保留✅ 参数保留编程式导航router.push({ name: user, params: { id: 123 } })router.push({ path: /user, query: { id: 123 } })使用 name 导航✅ 必须配合name使用✅ 可配合path或name使用 path 导航❌ 不能使用 params✅ 可以使用 queryURL 编码自动编码自动编码嵌套路由支持多层嵌套不涉及嵌套关系SEO 友好度较高路径包含关键词一般参数在查询字符串数据类型字符串字符串或数组重复参数典型用途资源 ID、唯一标识符筛选、分页、搜索关键词详细说明与代码示例1. 定义方式对比// 路由配置 const routes [ { // params: 在路径中定义 path: /user/:id/profile, name: user-profile, component: UserProfile }, { // query: 路径中不定义参数 path: /user/profile, name: user-profile-query, component: UserProfile } ]2. URL 格式对比// params 格式 URL: /user/123/profile // params 对象: { id: 123 } // query 格式 URL: /user/profile?id123page1sortdesc // query 对象: { id: 123, page: 1, sort: desc }3. 编程式导航对比script setup import { useRouter } from vue-router const router useRouter() // params 导航 // ✅ 正确必须使用 name router.push({ name: user-profile, params: { id: 123 } }) // 结果: /user/123/profile // ❌ 错误path params 不生效 router.push({ path: /user/profile, params: { id: 123 } // 会被忽略 }) // 结果: /user/profile (参数丢失) // query 导航 // ✅ 方式1: 使用 path query router.push({ path: /user/profile, query: { id: 123, page: 1 } }) // 结果: /user/profile?id123page1 // ✅ 方式2: 使用 name query router.push({ name: user-profile-query, query: { id: 123, page: 1 } }) // 结果: /user/profile?id123page1 /script4. 获取参数对比script setup import { useRoute } from vue-router const route useRoute() // params 获取 // URL: /user/123/profile console.log(route.params.id) // 123 console.log(route.params) // { id: 123 } // query 获取 // URL: /user/profile?id123page1tagsvuetagsrouter console.log(route.query.id) // 123 console.log(route.query.page) // 1 console.log(route.query.tags) // [vue, router] (重复参数转为数组) console.log(route.query) // { id: 123, page: 1, tags: [vue, router] } /script5. 嵌套路由对比// 路由配置 const routes [ { path: /user/:userId, component: UserLayout, children: [ { // params 支持嵌套 path: profile/:profileId, name: user-profile, component: UserProfile }, { // query 不受嵌套影响 path: settings, name: user-settings, component: UserSettings } ] } ] // params 嵌套访问 // URL: /user/123/profile/456 // route.params: { userId: 123, profileId: 456 } // query 在任何层级都可以 // URL: /user/123/settings?tabaccountnotifytrue // route.query: { tab: account, notify: true }6. 刷新页面行为对比script setup import { useRoute } from vue-router const route useRoute() // 页面刷新后 // URL: /user/123/profile // ✅ params 仍然存在 console.log(route.params.id) // 123 // URL: /user/profile?id123 // ✅ query 仍然存在 console.log(route.query.id) // 123 // 两者刷新后都不会丢失 /script7. 数据类型处理script setup import { useRoute } from vue-router const route useRoute() // params 始终是字符串 // URL: /user/123/profile const userId route.params.id // 123 (字符串) const numericId Number(route.params.id) // 需要手动转换 // query 支持多值 // URL: /list?tagsvuetagsreacttagsangular const tags route.query.tags // [vue, react, angular] (数组) // 单个值的情况 // URL: /list?page1 const page route.query.page // 1 (字符串) // 参数不存在时 const sort route.query.sort // undefined /script8. 实际应用场景template div !-- params 场景用户详情页 -- div v-ifroute.params.id h1用户详情/h1 p用户ID: {{ route.params.id }}/p button clickfetchUser(route.params.id) 加载用户 /button /div !-- query 场景商品列表页 -- div h1商品列表/h1 !-- 筛选条件 -- select v-modelfilters.category option valueelectronics电子产品/option option valueclothing服装/option /select input v-modelfilters.keyword placeholder搜索 / !-- 分页 -- div classpagination button clickchangePage(currentPage - 1)上一页/button span第 {{ currentPage }} 页/span button clickchangePage(currentPage 1)下一页/button /div !-- 排序 -- button clickchangeSort(price)按价格排序/button /div /div /template script setup import { useRoute, useRouter } from vue-router import { reactive, watch } from vue const route useRoute() const router useRouter() // params 场景获取用户ID const userId route.params.id // 资源标识符 // query 场景获取筛选条件 const filters reactive({ category: route.query.category || all, keyword: route.query.keyword || , page: Number(route.query.page) || 1, sort: route.query.sort || default }) // 监听筛选条件变化更新 URL query watch(filters, () { router.push({ path: /products, query: { category: filters.category, keyword: filters.keyword, page: filters.page, sort: filters.sort } }) }, { deep: true }) // 翻页函数 function changePage(page) { if (page 1) return filters.page page router.push({ path: /products, query: { ...route.query, page } }) } // 排序函数 function changeSort(sortBy) { filters.sort sortBy router.push({ path: /products, query: { ...route.query, sort: sortBy } }) } /script9. 使用场景选择指南场景推荐使用原因用户详情页paramsID 是资源的唯一标识在路径中更语义化文章详情页params/article/123比/article?id123更美观搜索关键词query可选参数适合/search?qvue分页参数query/list?page2符合 RESTful 规范筛选条件query多条件组合可选且可分享链接排序参数query可选参数不影响路由结构多选框值query支持数组如?tagsvuetagsreactTab 切换query或params如果 Tab 是资源的一部分用 params否则用 query10. 完整示例电商列表页script setup import { useRoute, useRouter } from vue-router import { ref, watch } from vue const route useRoute() const router useRouter() // 获取参数 // URL: /products/category/electronics?page2sortpricebrandapplebrandsamsung // params: 类别标识 const category route.params.category // electronics // query: 筛选条件 const page Number(route.query.page) || 1 const sort route.query.sort || default const brands route.query.brand || [] // [apple, samsung] // 构建筛选器 const filters ref({ page, sort, brands: Array.isArray(brands) ? brands : [brands] }) // 更新 URL function updateFilters() { router.push({ name: products-category, params: { category: category }, query: { page: filters.value.page, sort: filters.value.sort, brand: filters.value.brands } }) } // 监听筛选变化 watch(filters, updateFilters, { deep: true }) /script template div h1分类{{ category }}/h1 div classfilters select v-modelfilters.sort option valuedefault默认排序/option option valueprice价格排序/option option valuesales销量排序/option /select div classbrands label input typecheckbox valueapple v-modelfilters.brands Apple /label label input typecheckbox valuesamsung v-modelfilters.brands Samsung /label /div div classpagination button clickfilters.page--上一页/button span第 {{ filters.page }} 页/span button clickfilters.page下一页/button /div /div /div /template