路由器实例 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 记忆技巧


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

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| useRoute | useRouter |
| | |


1. 快速对比表

维度 useRouter useRoute
含义 路由器实例 当前路由信息
返回对象 Router 对象 Route 对象
主要用途 路由跳转、导航 获取路由参数、查询参数
常用方法/属性 push(), replace(), go(), back(), currentRoute params, query, path, name, meta, fullPath
类比 导航系统(控制器) 当前路况信息(数据)
记忆口诀 Router 是工具,Route 是数据

2. 核心记忆方法

方法一:词源记忆法

javascript 复制代码
// Router = 路由器(工具)
// - 用于控制路由:跳转、前进、后退
// - 类比:物理路由器,控制网络数据流向

// Route = 路由(信息)  
// - 用于获取信息:参数、查询字符串、路径
// - 类比:路线信息,告诉你当前在哪里

方法二:首字母记忆法

复制代码
R -> Router -> 控制 (Control)
R -> Route  -> 数据 (Data)

记住:Router 是动作,Route 是状态

方法三:英文含义记忆

javascript 复制代码
// Router = 路由器(名词-设备)
// - 你在"路由器"上执行操作
useRouter().push()   // 操作路由器
useRouter().back()   // 操作路由器

// Route = 路线(名词-信息)
// - 你获取"路线"上的信息
useRoute().params    // 获取路线参数
useRoute().query     // 获取路线查询参数

3. 使用场景对比

html 复制代码
<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. 形象化记忆

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

javascript 复制代码
// 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 中监听路由变化

javascript 复制代码
import { useRoute } from 'vue-router'
import { watch } from 'vue'

// ✅ 正确:监听 route 的变化
const route = useRoute()
watch(() => route.params.id, (newId) => {
  console.log('路由参数变化', newId)
})

6. 代码模板记忆法

html 复制代码
<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. 属性/方法速查表

需求 使用对象 代码示例
页面跳转 router router.push('/path')
返回上一页 router router.back()
前进/后退 router router.go(-1)
替换路由 router router.replace('/path')
获取 URL 参数 route route.params.id
获取查询参数 route route.query.page
获取当前路径 route route.path
获取路由名称 route route.name
获取路由元信息 route route.meta.title
监听路由变化 route watch(() => route.params)
获取完整 URL route route.fullPath
获取路由哈希 route route.hash

9. 常见错误及纠正

javascript 复制代码
// ❌ 错误 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. 质疑,对......表示疑问;询问,提问

对比维度 params query
定义 路由参数(路径参数) 查询参数(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. 定义方式对比

javascript 复制代码
// 路由配置
const routes = [
  {
    // params: 在路径中定义
    path: '/user/:id/profile',
    name: 'user-profile',
    component: UserProfile
  },
  {
    // query: 路径中不定义参数
    path: '/user/profile',
    name: 'user-profile-query',
    component: UserProfile
  }
]

2. URL 格式对比

javascript 复制代码
// 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. 编程式导航对比

javascript 复制代码
<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. 获取参数对比

html 复制代码
<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. 嵌套路由对比

javascript 复制代码
// 路由配置
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. 刷新页面行为对比

html 复制代码
<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. 数据类型处理

html 复制代码
<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. 实际应用场景

html 复制代码
<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. 使用场景选择指南

场景 推荐使用 原因
用户详情页 params ID 是资源的唯一标识,在路径中更语义化
文章详情页 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. 完整示例:电商列表页

html 复制代码
<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>
相关推荐
Irene199113 天前
Vue Router 中:route.params.id 和 route.query.id 的区别
vue.js·route·useroute
灵犀坠1 个月前
React+Node.js全栈实战:实现安全高效的博客封面图片上传(踩坑实录)
安全·react.js·node.js·router·query·clerk
曲幽2 个月前
FastAPI搭档Pydantic:从参数验证到数据转换的全链路实战
python·fastapi·web·path·field·query·pydantic·basemodel·response_model
这是个栗子2 个月前
【API封装参数传递】params 与 API 封装
开发语言·前端·javascript·data·params
曲幽3 个月前
一文理清FastAPI参数:从Query、Path到BaseModel的实战指南
python·fastapi·web·form·request·path·body·query·basemodel
教练、我想打篮球5 个月前
29 ip查询工具 并发送邮件通知目标用户
tcp/ip·ip·query
木木子99998 个月前
Pandas query() 方法详解
pandas·query
G皮T9 个月前
【Elasticsearch】全文检索 & 组合检索
大数据·elasticsearch·搜索引擎·全文检索·match·query·组合检索
一雨方知深秋1 年前
智慧商城:搜索页面基于商品名称进行搜索,分类页面点击商品进行搜索。(跳转到商品列表页面,地址栏携带的参数作为请求的参数进行请求,然后动态渲染)
前端·javascript·vue.js·axios·get·query·params