一、前言
在 Vue2 开发中,我们依托 this.$router 实现路由跳转,通过 this.$route 获取路由参数。但 Vue3 启用 <script setup> 组合式语法后,组件不再存在 this 实例,传统的原型调用方式彻底失效。
为此,Vue Router 4.x 推出两大核心组合式 API:useRouter、useRoute,作为 Vue3 项目路由操作的唯一标准写法。
很多开发者日常开发经常混淆二者用法,出现传参失效、页面刷新参数丢失、路由跳转异常、history历史错乱等问题。本文将从零落地讲解路由跳转、三种传参方案、参数接收规则、核心区别与企业级避坑技巧,适配零基础学习、项目实战与面试备考。
二、核心本质:useRouter 与 useRoute 终极区分
二者各司其职,核心定位完全不同,只需记住一句话:Router 管操作,Route 管读取。
- useRouter(路由操作器) :对应 Vue2 的
this.$router,负责写操作。用于主动实现页面跳转、路由替换、清空历史记录、控制路由逻辑。 - useRoute(路由读取器) :对应 Vue2 的
this.$route,负责读操作。为只读属性,用于获取当前页面路径、路由参数、路由名称、meta元信息等。
三、基础路由跳转:push 最常用场景
useRouter.push 是项目中最高频的路由跳转方式,跳转页面后会追加一条浏览器历史记录,支持点击返回按钮回退上一页,适用于绝大多数正常页面跳转场景。
标准语法示例(Vue3 setup 完整版)
xml
<script setup>
// 引入路由核心方法
import { useRouter } from 'vue-router'
// 生成路由实例
const router = useRouter()
// 普通页面跳转
const goHome = () => {
router.push('/home')
}
</script>
四、Vue3 三种路由传参方案(全覆盖项目场景)
Vue3 路由传参分为三种主流方式:params隐式传参、query显式传参、动态路由传参。三种方式的语法规则、URL展示、刷新机制、安全性完全不同,绝对禁止随意混用。
1、params 隐式传参(name + params 固定搭配)
核心强制规则 :params 只能搭配 路由 name 使用,绝对不能和 path 混用,否则参数直接失效。
特点:参数不会拼接在浏览器 URL 地址栏中,隐藏传输、私密性更强,适合传递临时私密参数。
1.1 路由前置配置(必须声明 name)
javascript
import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'
const routes = [
{
path: '/home',
name: 'Home', // params传参必须依赖路由name属性
component: Home
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
1.2 父组件传参写法
xml
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const goHome = () => {
router.push({
name: 'Home', // 匹配路由配置的name
params: {
username: '前端开发者',
id: 1001
}
})
}
</script>
1.3 子组件接收参数
xml
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// 读取params参数
console.log(route.params)
console.log(route.params.username)
console.log(route.params.id)
</script>
2、query 显式传参(path + query 固定搭配)
核心强制规则 :query 必须搭配 路由 path 使用,参数会明文拼接在 URL 地址栏末尾。
特点:类似 GET 请求传参,参数公开透明,页面刷新参数不会丢失,适合传递公开、需要持久展示的参数。
2.1 父组件传参写法
xml
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const goHome = () => {
router.push({
path: '/home', // 匹配路由路径
query: {
username: '前端开发者',
id: 1001
}
})
}
</script>
2.2 子组件接收参数
xml
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// 读取query参数
console.log(route.query)
console.log(route.query.username)
console.log(route.query.id)
</script>
3、动态路由传参(路径占位传参)
通过在路由配置中声明 :参数名 作为动态占位符,实现页面跳转传参,是项目详情页、ID匹配页面的主流方案。
适用场景:仅用于传递 ID、唯一标识、序号等简单基础数据类型。
3.1 路由配置动态占位符
javascript
const routes = [
{
path: '/detail/:id', // :id 动态参数占位符
name: 'Detail',
component: () => import('@/views/Detail.vue')
}
]
3.2 父组件跳转传参
xml
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
// 直接拼接动态参数跳转
const goDetail = () => {
router.push('/detail/1001')
}
</script>
3.3 子组件接收动态参数
动态路由匹配的参数,会自动挂载到 route.params 中。
xml
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// 获取动态路由参数
console.log(route.params.id)
</script>
五、query 与 params 核心区别(面试高频必背)
- URL展示差异:query 参数明文展示在地址栏;params 参数隐藏不展示,私密性更好。
- 刷新机制差异 :query 刷新页面参数永久保留;params 刷新页面参数直接丢失。
- 搭配规则差异:query 绑定 path 使用,params 绑定 name 使用,二者严禁混搭。
- 适用场景差异:公开参数、筛选条件用 query;临时私密参数、页面临时交互数据用 params。
- 编码体验差异:原生截取URL参数易出现转码报错,统一使用 useRoute 取值,可自动处理转码问题,零BUG。
六、push 与 replace 跳转模式核心差异
1、push 跳转(追加历史记录)
跳转后新增一条浏览器历史记录,用户可点击返回按钮回退上一页。适用于列表跳转详情、普通页面流转等绝大多数业务场景。
2、replace 跳转(替换历史记录)
跳转时直接替换当前页面的历史记录,不会新增历史条目,用户无法回退到上一页。适用于登录成功跳转、结果页跳转、404页面等禁止回退的场景。
写法一:直接调用 replace
xml
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const goDetail = () => {
router.replace('/detail/1001')
}
</script>
写法二:push 配置 replace:true(等效替换)
xml
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const goDetail = () => {
router.push({
path: '/detail/1001',
replace: true
})
}
</script>
七、企业级开发避坑总结(高频BUG解决方案)
- 禁止混搭传参:path 只能搭配 query,name 只能搭配 params,混搭直接导致参数失效。
- params 参数不持久:刷新页面params参数会丢失,重要业务数据禁止用params传递,需持久化可配合 localStorage。
- 动态传参局限性:仅支持简单数据类型,对象、数组等复杂数据优先使用 params 传参。
- 统一取值规范:摒弃原生URL截取参数的方式,全程使用 useRoute 取值,规避转码、空值等异常问题。
- 合理使用replace:登录跳转、支付结果页、提交成功页优先用replace,避免用户回退触发重复操作。
八、全文终极总结
Vue3 组合式路由 API 核心逻辑高度统一,只需记住两大核心、三类场景:
- useRouter:负责所有路由跳转动作,push 追加页面、replace 替换页面。
- useRoute:负责所有路由参数读取,统一获取 query、params、动态路由参数、路由元信息。
- 公开持久参数用 query,临时私密参数用 params,ID类唯一标识用动态路由传参。
掌握以上规范,可彻底解决 Vue3 路由传参失效、刷新丢失、跳转异常等99%的项目问题,写出规范、优雅、零BUG的企业级路由代码。
九、高频实战补充:路由参数监听(解决页面不刷新BUG)
在 Vue3 项目中,存在一个经典疑难问题:同一路由页面,仅参数变化时,组件不会重新渲染,页面数据不会自动更新。比如列表页点击不同 ID 跳转详情页、筛选参数切换页面,视图无刷新、数据不更新。
Vue2 中可通过 watch 监听 $route 解决,Vue3 setup 语法下,需搭配 watch + useRoute 实现路由参数实时监听,是企业级开发必备技能。
1、基础监听:监听整个路由对象
适合路由任意参数、路径变化都需要刷新数据的场景,开启深度监听即可响应所有路由变化。
xml
<script setup>
import { useRoute } from 'vue-router'
import { watch } from 'vue'
const route = useRoute()
// 监听整个路由变化
watch(
() => route,
(newVal) => {
console.log('路由发生变化', newVal)
// 重新请求接口、刷新页面数据
getPageData()
},
{ deep: true }
)
// 模拟页面接口请求
const getPageData = () => {
console.log('最新ID:', route.params.id || route.query.id)
}
</script>
2、精准监听:只监听指定参数(推荐企业级用法)
全局监听整个路由会产生多余触发,性能不佳。日常开发精准监听 params / query 指定参数,按需触发接口请求,性能更优、逻辑更严谨。
xml
<script setup>
import { useRoute } from 'vue-router'
import { watch } from 'vue'
const route = useRoute()
// 精准监听 query 中 id 参数变化
watch(
() => route.query.id,
(newId) => {
if (newId) {
// 参数变化,重新拉取详情数据
getDetailData(newId)
}
}
)
// 精准监听 params 中 id 参数变化
watch(
() => route.params.id,
(newId) => {
if (newId) {
getDetailData(newId)
}
}
)
const getDetailData = (id) => {
console.log('刷新详情数据,ID:', id)
}
</script>
3、高级优化:首次进入+参数变化统一触发
默认 watch 仅监听参数变化,页面首次加载不会触发。搭配 immediate: true可实现页面初始化、路由参数变更双向触发,精简冗余代码,无需单独调用接口。
scss
// 首次进入 + 参数变化 自动请求数据
watch(
() => route.params.id,
(newId) => {
newId && getDetailData(newId)
},
{ immediate: true }
)
4、路由监听核心避坑要点
- 禁止滥用深度监听:无需监听整个路由对象,精准监听所需参数,减少无效渲染、优化页面性能
- 搭配immediate按需使用:需要页面初始化加载接口就开启,无需首次加载则关闭,避免重复请求
- 区分params/query监听:根据自身传参方式监听对应参数,避免监听错误导致数据不刷新
- 规避重复请求:可搭配 loading 状态锁,防止路由快速切换触发多次接口请求
十、路由全套最终总结(面试+项目完整版)
整合路由跳转、传参、历史模式、参数监听全套核心逻辑,一文吃透Vue3路由:
- 核心API区分:useRouter负责跳转操作,useRoute负责参数读取,各司其职不混用
- 传参规范:path+query公开持久、name+params私密临时、动态路由传ID标识
- 跳转模式:push追加历史可回退,replace替换历史禁止回退
- 页面刷新解决方案:同路由参数变化不刷新,用watch精准监听路由参数即可解决
- 开发准则:杜绝参数混搭、摒弃原生截取URL、合理使用replace、精准监听路由变化,写出零BUG企业级路由代码