当前位置: 首页 > news >正文

路由器实例 useRouter,当前路由信息 useRoute(params, query)

Vue Router中useRouter和useRoute的区别与记忆技巧


useRouter用于控制路由跳转(push/replace/go等方法),相当于路由器工具;


useRoute用于获取当前路由信息(params/query/path等),相当于路由数据。


记忆口诀:"Router跳转,Route参数"。


核心区分:

  1. useRouter返回Router实例,用于导航操作
  2. useRoute返回Route对象,包含当前路由信息
  3. 类比:Router是导航系统(控制器),Route是路况信息(数据)

常见错误:

  1. 混淆变量名(router/route)
  2. 在setup外部使用
  3. 解构失去响应性

参数对比:

  • params:路径参数(/user/123),必须定义在路由配置中
  • query:查询参数(?id=123),无需预定义,支持多值

useRouter vs useRoute 记忆技巧


这是一个非常常见的混淆点!

useRouteuseRouter

1. 快速对比表

维度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`) } </script>

4. 形象化记忆

把路由比作"公交车系统"

// 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`) } </script>

7. 记忆口诀

口诀一(中文)

text

Router 跳转,Route 参数 想要跳转找 Router 想要参数找 Route

口诀二(英文)

text

Router 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.hash

9. 常见错误及纠正

// ❌ 错误 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 的复数)


query:n. 疑问,询问问号; v. 质疑,对……表示疑问;询问,提问

对比维度paramsquery
定义路由参数(路径参数)查询参数(URL 参数)
位置在 URL 路径中在 URL 问号?后面
URL 示例/user/123/profile/user/profile?id=123
定义方式路由配置中定义:param无需预定义,直接使用
路由配置path: '/user/:id/profile'path: '/user/profile'
必须性必须在路由规则中定义可选,无需预定义
刷新页面✅ 参数保留✅ 参数保留
编程式导航router.push({ name: 'user', params: { id: 123 } })router.push({ path: '/user', query: { id: 123 } })
使用 name 导航✅ 必须配合name使用✅ 可配合pathname
使用 path 导航❌ 不能使用 params✅ 可以使用 query
URL 编码自动编码自动编码
嵌套路由支持多层嵌套不涉及嵌套关系
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?id=123&page=1&sort=desc // 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?id=123&page=1 // ✅ 方式2: 使用 name + query router.push({ name: 'user-profile-query', query: { id: 123, page: 1 } }) // 结果: /user/profile?id=123&page=1 </script>

4. 获取参数对比

<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?id=123&page=1&tags=vue&tags=router 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"] } </script>

5. 嵌套路由对比

// 路由配置 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?tab=account&notify=true // 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?id=123 // ✅ query 仍然存在 console.log(route.query.id) // "123" // 两者刷新后都不会丢失 </script>

7. 数据类型处理

<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?tags=vue&tags=react&tags=angular const tags = route.query.tags // ["vue", "react", "angular"] (数组) // 单个值的情况 // URL: /list?page=1 const page = route.query.page // "1" (字符串) // 参数不存在时 const sort = route.query.sort // undefined </script>

8. 实际应用场景

<template> <div> <!-- params 场景:用户详情页 --> <div v-if="route.params.id"> <h1>用户详情</h1> <p>用户ID: {{ route.params.id }}</p> <button @click="fetchUser(route.params.id)"> 加载用户 </button> </div> <!-- query 场景:商品列表页 --> <div> <h1>商品列表</h1> <!-- 筛选条件 --> <select v-model="filters.category"> <option value="electronics">电子产品</option> <option value="clothing">服装</option> </select> <input v-model="filters.keyword" placeholder="搜索" /> <!-- 分页 --> <div class="pagination"> <button @click="changePage(currentPage - 1)">上一页</button> <span>第 {{ currentPage }} 页</span> <button @click="changePage(currentPage + 1)">下一页</button> </div> <!-- 排序 --> <button @click="changeSort('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 } }) } </script>

9. 使用场景选择指南

场景推荐使用原因
用户详情页paramsID 是资源的唯一标识,在路径中更语义化
文章详情页params/article/123/article?id=123更美观
搜索关键词query可选参数,适合/search?q=vue
分页参数query/list?page=2符合 RESTful 规范
筛选条件query多条件组合,可选且可分享链接
排序参数query可选参数,不影响路由结构
多选框值query支持数组,如?tags=vue&tags=react
Tab 切换queryparams如果 Tab 是资源的一部分用 params,否则用 query

10. 完整示例:电商列表页

<script setup> import { useRoute, useRouter } from 'vue-router' import { ref, watch } from 'vue' const route = useRoute() const router = useRouter() // 获取参数 // URL: /products/category/electronics?page=2&sort=price&brand=apple&brand=samsung // 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 class="filters"> <select v-model="filters.sort"> <option value="default">默认排序</option> <option value="price">价格排序</option> <option value="sales">销量排序</option> </select> <div class="brands"> <label> <input type="checkbox" value="apple" v-model="filters.brands"> Apple </label> <label> <input type="checkbox" value="samsung" v-model="filters.brands"> Samsung </label> </div> <div class="pagination"> <button @click="filters.page--">上一页</button> <span>第 {{ filters.page }} 页</span> <button @click="filters.page++">下一页</button> </div> </div> </div> </template>
http://www.jsqmd.com/news/538136/

相关文章:

  • 美超微案件凸显人工智能基础设施供应链风险
  • 2026年共话防火门实力厂商,南京泰瀚科技获客户认可 - 工业品牌热点
  • 保姆级教程:在Next.js App Router项目中,从API路由到前端按钮的完整删除流程
  • 股票可视化的毕设:从零构建一个可交互的金融数据看板(新手入门实战)
  • 上海高端腕表鉴定维修全攻略:38个奢华品牌故障解析+六城门店实测(含2026权威数据) - 时光修表匠
  • 一键解决中文文献管理痛点:茉莉花插件让Zotero效率提升90%的完整指南
  • DataEyes聚合平台新API接入实战指南:从0到1打通实时数据链路
  • 如何3分钟搞定本地语音转文字:TMSpeech终极高效方案
  • 从 nvm 到 Volta:前端工具链管理的演进与自动化实践
  • 别再对着手册发愁了!手把手教你用Vivado配置Xilinx FFT IP核(附时序仿真与资源优化技巧)
  • 微信聊天记录备份指南:3步轻松保护你的珍贵回忆
  • 智能客服Agent实战:从零搭建高可用对话系统的全流程指南
  • RK3568 Android12长按电源键无反应?三步搞定关机菜单恢复
  • 从原理到实践:Matlab相机标定参数详解与坐标变换全流程
  • MZmine 3:开源质谱数据处理软件的终极实战指南
  • Phi-4-Reasoning-Vision开发者案例:与LangChain集成实现多跳图文推理链
  • 颈肩痛分急性和慢性,对症缓解才有效
  • Magisk Root技术实践指南:从决策评估到风险管控的完整解决方案
  • 德希科技在线电导率传感器
  • Onekey智能管理:Steam游戏数据整合的效率工具解决方案
  • 企业IT必看:教员工用小米手机配置Exchange邮箱的完整指南(含服务器参数详解)
  • GPT-4o 实战:如何用 ChatGPT API 提升开发效率的 5 个关键技巧
  • 如何通过zotero-style实现文献管理效率提升:7个实用技巧
  • 避坑指南:AUTOSAR COM DeadlineMonitor配置中的那些“坑”与最佳实践
  • 深度拆解贪心算法:从“局部最优”到“全局最优”,看完这两个案例你就懂了
  • 手把手教你用FM25V02A-FRAM芯片替换树莓派项目中的EEPROM(附SPI配置代码)
  • ngx_write_file
  • 盘点推荐:2026年AI智能CRM系统主流品牌 - SaaS软件-点评
  • 解决洛雪音乐源下载异常:从诊断到优化的完整指南
  • Gemini vs 文心一言 2026深度评测:国内AI大模型谁更适合开发者?