2、静态路由:声明式导航、编程式导航、路由参数传递(query/params)
好,咱们进入第二个实战环节。
静态路由,说白了就是路由表写死了的那种。你定义好路径,组件就固定在那里。虽然听起来简单,但这里面的门道可不少。我刚开始用 Vue Router 的时候,就老在导航方式和参数传递上栽跟头。
今天咱们就把这块彻底捋清楚。
2.1 声明式导航:<router-link> 的正确用法
声明式导航,就是你在模板里写 <router-link> 标签。它最终会被渲染成一个 <a> 标签。
我个人习惯,只要页面里有固定的导航菜单,一律用声明式。为什么?因为可读性好,而且 Vue Router 会自动处理高亮状态。
核心用法:
<!-- 基本用法 -->
<router-link to="/home">首页</router-link>
<!-- 带参数:query 方式 -->
<router-link :to="{ path: '/user', query: { id: 123, name: '张三' } }">
用户详情
</router-link>
<!-- 带参数:params 方式(需要配合命名路由) -->
<router-link :to="{ name: 'UserDetail', params: { id: 456 } }">
用户详情
</router-link>
这里有个坑,我必须要说。
我曾经踩过的坑:
用 params 的时候,千万不能用 path 来搭配。你写 :to="{ path: '/user', params: { id: 1 } }",params 会被直接忽略掉。嗯,Vue Router 就是这么设计的。必须用 name 来指定路由。
2.2 编程式导航:this.$router.push 与 replace
编程式导航,就是在 JavaScript 代码里跳转。比如用户登录成功后,或者某个异步操作完成后,你需要手动跳转。
我一般用 this.$router.push 居多。它会在历史栈里加一条记录,用户点浏览器「后退」按钮能回去。
// 编程式导航示例
methods: {
goToUser(id) {
// query 方式
this.$router.push({ path: '/user', query: { id: id } })
// params 方式(命名路由)
this.$router.push({ name: 'UserDetail', params: { id: id } })
},
// 替换当前记录,不留下历史
replaceToHome() {
this.$router.replace('/home')
},
// 前进/后退
goBack() {
this.$router.go(-1)
}
}
我的小建议:
如果你在做表单提交,提交成功后用 replace 跳转。这样用户点后退,不会回到那个已经提交过的表单页面。用户体验会好很多。
2.3 路由参数传递:query vs params
这两个东西,很多新手搞混。其实区别很简单,我直接给你列个表。
| 对比项 | query | params |
|---|---|---|
| URL 形式 | /user?id=123&name=张三 |
/user/123(需路由配置 /user/:id) |
| 刷新后是否丢失 | 不丢失 | 不丢失(但需配置路由参数) |
| 获取方式 | $route.query |
$route.params |
| 适用场景 | 搜索条件、筛选参数 | 资源 ID、唯一标识 |
你想想看,为什么会有这两种方式?
说白了,query 适合那种「可选」的参数。比如搜索关键词,用户可能不传,URL 里就没有 ?keyword=xxx。而 params 适合「必选」的参数,比如用户 ID,没有 ID 你显示谁的信息?
实战中的参数获取:
// 在组件中获取参数
export default {
created() {
// 获取 query 参数
const id = this.$route.query.id
const name = this.$route.query.name
// 获取 params 参数
const userId = this.$route.params.id
console.log('query:', id, name)
console.log('params:', userId)
}
}
2.4 路由配置与参数绑定
要让 params 生效,你得先在路由配置里定义好参数占位符。
// router/index.js
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/user',
name: 'User',
component: User
},
{
// 注意这里的 :id,就是 params 的占位符
path: '/user/:id',
name: 'UserDetail',
component: UserDetail
},
{
// 多个参数
path: '/post/:year/:month/:day',
name: 'PostDetail',
component: PostDetail
}
]
我在项目中遇到过一个问题:用户直接访问 /user 和 /user/123,其实是两个不同的路由。如果你想让它们共用同一个组件,可以用 props 来解耦。
推荐做法:
把 $route 的耦合降到最低。用 props: true 把参数变成组件的 props。
// 路由配置
{
path: '/user/:id',
component: UserDetail,
props: true // 自动将 params 作为 props 传入
}
// 组件中直接接收
export default {
props: ['id'],
mounted() {
console.log(this.id) // 直接使用,不用再 $route.params.id
}
}
这样组件更干净,也更容易测试。我个人强烈推荐这种方式。
2.5 常见问题与避坑指南
嗯,这里我总结几个我踩过的坑,你遇到了直接对照着看就行。
我曾经踩过的坑:
- params 刷新丢失? 如果你用
$router.push({ name: 'User', params: { id: 1 } }),但路由配置里没有/user/:id这个路径,刷新后 params 就没了。记住:params 必须和路由路径中的占位符对应。 - query 参数太长? 有些浏览器对 URL 长度有限制(比如 IE 的 2083 字符)。如果你传大量数据,别用 query,考虑用 params 或者 Vuex。
- 同一个路由,参数变了但组件不刷新? 这是 Vue Router 的复用机制。解决方案:用
watch监听$route变化,或者给<router-view>加:key="$route.fullPath"。
// 监听路由变化的正确姿势
export default {
watch: {
'$route'(to, from) {
// 路由变化时重新获取数据
this.fetchData(to.params.id)
}
},
methods: {
fetchData(id) {
// 你的数据请求逻辑
}
}
}
好了,静态路由这块就这些。说白了就是三件事:怎么跳、怎么传参、怎么拿参数。你把这三点搞明白,后面动态路由就好理解了。
下一节咱们聊动态路由匹配,那个才是真正体现 Vue Router 灵活性的地方。