学习笔记:Vue Router 编程式导航详解
1. 核心概念重述
在 Vue.js 应用中,除了使用 <router-link>
进行声明式路由跳转外,还可以通过调用路由器实例的方法实现编程式导航。这种方式允许我们在逻辑代码中动态控制页面跳转,适用于按钮点击、表单提交、权限判断等场景。
2. 编程式导航方法概览
方法 | 对应声明式 | 功能描述 |
---|---|---|
router.push() | <router-link :to="..."> | 导航到新路径,并在浏览器历史中添加一条记录 |
router.replace() | <router-link :to="..." replace> | 导航并替换当前历史记录,不会保留原页面 |
router.go(n) | —— | 在历史记录中前进或后退 n 步 |
3. 详解三大导航方法
✅ router.push(path)
用于导航到新的 URL,并将该记录添加到浏览器的 history 栈中。
使用方式:
// 字符串路径
router.push('/users/eduardo')// 路径对象
router.push({ path: '/users/eduardo' })// 命名路由 + 参数(推荐)
router.push({ name: 'user', params: { username: 'eduardo' } })// 查询参数
router.push({ path: '/register', query: { plan: 'private' } }) // /register?plan=private// Hash 片段
router.push({ path: '/about', hash: '#team' }) // /about#team
⚠️ 注意:如果提供了
path
,则params
会被忽略。必须使用name
或手动拼接路径来传递参数。
const username = 'eduardo'// ❌ 错误:path 与 params 不兼容
router.push({ path: '/user', params: { username } }) // 结果为 /user// ✅ 正确:使用 name
router.push({ name: 'user', params: { username } }) // /user/eduardo// ✅ 正确:手写完整 path(需自行编码)
router.push({ path: `/user/${username}` })
返回 Promise
router.push({ name: 'user', params: { username: 'eduardo' } }).then(() => {console.log('导航成功')}).catch(err => {if (err.name !== 'NavigationFailure') {console.error('导航失败:', err)}})
这使得我们可以处理导航异常(如重复导航、权限不足等)。
✅ router.replace(path)
与 push
类似,但不向 history 添加新记录,而是替换当前条目。
使用方式:
// 方式一:直接调用 replace
router.replace('/home')// 方式二:在 push 中设置 replace: true
router.push({ path: '/home', replace: true })
应用场景:登录后跳转首页,用户按“返回”不应回到登录页。
✅ router.go(n)
在浏览器历史栈中移动指定步数。
router.go(1) // 前进一步,相当于 forward()
router.go(-1) // 后退一步,相当于 back()
router.go(3) // 前进三步
router.go(-100)// 若历史不足,则静默失败
Vue Router 模拟了 window.history.go(n)
的行为,无论使用何种 history 模式(hash、history、abstract),均可正常工作。
4. 在组件中的访问方式
选项式 API(Options API)
通过 this.$router
访问:
<script>
export default {methods: {goToUser() {this.$router.push({ name: 'user', params: { username: 'alice' } })},goBack() {this.$router.go(-1)}}
}
</script>
组合式 API(Composition API)
使用 useRouter()
钩子:
<script setup>
import { useRouter } from 'vue-router'const router = useRouter()function navigateToHome() {router.push('/')
}function replaceAndGo() {router.replace({ path: '/dashboard', query: { from: 'login' } })
}
</script>
5. 参数传递规则总结
类型 | 写法 | 示例 | URL 输出 |
---|---|---|---|
path 字符串 | router.push('/path') | /user/eduardo | /user/eduardo |
path + query | { path: '', query: {} } | { path: '/search', query: { q: 'vue' } } | /search?q=vue |
path + hash | { path: '', hash: '' } | { path: '/info', hash: '#top' } | /info#top |
name + params | { name: '', params: {} } | { name: 'user', params: { username: 'bob' } } | /user/bob (需路由定义支持) |
❌ path + params | 不支持 | { path: '/user', params: { id: 1 } } | /user (params 被忽略) |
💡 推荐:优先使用 命名路由 + params,可自动进行 URL 编码,避免手动处理特殊字符。
6. 路由跳转对比图表示意
7. 常见问题与最佳实践
❓为什么 params
在 path
下无效?
因为 params
只有在通过 name
匹配路由时才生效。Vue Router 需要根据路由名称查找对应的模式(如 /user/:username
)才能正确填充参数。
✅ 正解:
router.push({ name: 'user', params: { username: 'john' } })
❌ 错误:
router.push({ path: '/user', params: { username: 'john' } }) // params 被丢弃
🛠️ 如何安全地拼接带参数的路径?
使用模板字符串并配合 encodeURIComponent
:
const username = '张三'
router.push(`/user/${encodeURIComponent(username)}`)
或者更推荐的方式是使用 name
和 params
,由框架自动编码。
✅ 编程式导航的优势
条件跳转(如登录验证)
表单提交后跳转
异常处理后跳转错误页
动态构建目标路径
支持 Promise 处理导航结果
8. 总结归纳
方法 | 是否新增 history 记录 | 是否可返回 | 典型用途 |
---|---|---|---|
push() | ✅ 是 | ✅ 可返回 | 正常跳转 |
replace() | ❌ 否 | ❌ 不可返回 | 登录跳转、防止回退 |
go(n) | —— | 控制前进后退 | 自定义导航逻辑 |
9. 知识点
$router 与 useRouter():在组件中访问路由器实例的方式,选项式用
this.$router
,组合式用useRouter()
。命名路由与 params:通过
name
和params
实现安全参数传递,避免手动编码 URL。history 操作机制:
push
、replace
、go
分别对应浏览器 history 的三种操作,模拟其行为且跨模式兼容。