一、to在vue router里扮演啥角色?
做Vue项目时,路由跳转是绕不开的环节,而vue - router里的「to」总在各种跳转场景里出现,不少刚入门的同学会疑惑:这to到底是干啥的?怎么用才能让路由跳转既顺手又不出错?今天咱们就把to的用法、门道拆明白,从基础到实战一次性讲透。
简单说,to是“路由跳转目标”的载体——不管是用声明式的<router - link>组件,还是编程式的router.push()这类方法,to的作用都是告诉vue - router“我要跳转到哪个路由”。
打个比方:你想去商场某家店(目标路由),<router - link>就像“导航指引牌”,to是牌上写的“店铺位置”;router.push()这类方法像“手机导航APP”,to是你在APP里输入的“目的地”,没有to,vue - router根本不知道该往哪跳,所以它是路由跳转的核心配置项。
里的to咋用?
<router - link>是Vue里声明式导航的核心组件(不用写JS逻辑,靠HTML标签实现跳转),它的to属性有两种玩法:
字符串形式(直接写路径)
最基础的用法是把目标路由的路径字符串丢给to,
<router - link to="/home">跳转到首页</router - link> <router - link to="/user/123">跳转到ID为123的用户页</router - link>
这种方式简单直接,但有个问题:如果项目后期调整了路由路径(比如把/user改成/member),所有写死路径的地方都得改,维护起来麻烦。
对象形式(灵活配置路由)
为了更灵活,to还支持对象格式,里面能配name(路由命名)、path(路径)、params(动态参数)、query(查询参数)这些属性,举个栗子:
<router - link
:to="{
name: 'UserDetail', // 路由的name(路由配置里定义的)
params: { id: 123 }, // 动态参数,对应路由里的/:id
query: { tab: 'info' } // 查询参数,会显示在url?后面
}"
>跳转到用户详情</router - link>
这里得注意路由配置要和参数对应上,比如路由配置如果是:
{
path: '/user/:id',
name: 'UserDetail',
component: UserDetail
}
那params.id必须传,否则匹配不到路由;而query是可选的,用来附加额外信息(比如tab切换标识)。
编程式导航里的to咋玩?
除了声明式的<router - link>,Vue里还有编程式导航(靠JS代码触发跳转),比如this.$router.push()、this.$router.replace()、this.$router.go()这些方法,这里的to和<router - link>的to逻辑一样,也是字符串或对象形式。
场景:按钮点击跳转
比如页面有个“去关于页”的按钮,点击时用编程式导航:
<button @click="goAbout">去关于页</button>
export default {
methods: {
goAbout() {
// 字符串形式
this.$router.push('/about');
// 对象形式(假设路由name是About)
this.$router.push({ name: 'About' });
}
}
}
带参数的编程式跳转
如果要跳转到“商品详情页”并传商品ID,用对象形式更灵活:
goProductDetail(productId) {
this.$router.push({
name: 'ProductDetail',
params: { id: productId },
query: { from: 'home' }
});
}
路由配置得对应/product/:id,这样跳转后url会变成/product/100?from = home,目标组件里可以用this.$route.params.id和this.$route.query.from拿到参数。
命名路由的优势
前面提到用name而不是path,好处是路由路径变化时,只要name不变,代码不用改,比如路由配置从path: '/product'改成path: '/goods',只要name: 'ProductDetail'还在,所有用name跳转的地方都不用动,维护性拉满。
to里传参有啥讲究?
用to传参时,params和query是最常用的两种方式,但它们的作用、显示方式、是否必填完全不同,得搞清楚区别:
params:动态路由的“必填项”
params是给动态路由段传值的(路由配置里带的部分,比如/user/:id里的:id),特点是:
- 必须和路由配置的动态段一一对应,否则路由匹配失败(比如少传id会跳404);
- 传参后,参数会嵌入到url路径里(比如
/user/123),刷新页面参数不会丢(因为在url里); - 如果用
path配to,传params会失效!// 错误写法:用path时传params不生效 this.$router.push({ path: '/user', params: { id: 123 } }); // 正确写法:用name + params,或者path直接写全 this.$router.push({ name: 'User', params: { id: 123 } }); this.$router.push('/user/123');
query:附加信息的“可选包”
query是给路由附加查询参数的(类似url里的?xxx = xxx),特点是:
- 属于“额外信息”,不传也能跳转,路由配置里不需要提前定义;
- 传参后,参数会跟在url的?后面(比如
/home?tab = news); - 刷新页面时,query参数默认会保留(因为在url里),但如果是单页应用部署在History模式下,服务器没配置的话可能有问题,不过这是另一个话题了~
目标组件怎么收参?
不管是params还是query,目标组件里都得通过this.$route来拿(注意是$route不是$router!$router是路由实例,用来跳转;$route是当前路由信息对象,存着参数、路径这些)。
比如在UserDetail组件里:
export default {
created() {
console.log(this.$route.params.id); // 拿动态参数
console.log(this.$route.query.tab); // 拿查询参数
}
}
to和其他路由跳转方式咋区分?
vue - router里跳转方法不少,to是它们的“目标配置”,但不同方法的跳转逻辑不一样,得分清:
router.push(to):添加新历史记录
最常用的跳转方式,点击跳转后,浏览器历史记录会新增一条,所以点击返回能回到上一页,比如从首页跳详情页,用push的话,返回能回到首页。
router.replace(to):替换当前历史记录
和push的区别是,它会替换掉当前的历史记录,比如在支付页完成支付后跳结果页,用replace的话,用户点返回不会回到支付页(避免重复支付),而是回到更前面的页面。
<router - link>里可以加replace属性实现同样效果:
<router - link to="/result" replace>跳转到结果页(替换记录)</router - link>
router.go(n):前进/后退历史记录
这个方法里没有to,而是传数字n,比如this.$router.go(-1)表示后退一页,this.$router.go(1)表示前进一页,它是操作浏览器历史记录的“前进后退”,和to负责的“指定目标”逻辑不同。
用to时容易踩的坑?
新手用to经常栽跟头,这些常见坑得提前避坑:
“path + params”传参失效
前面讲过,用path配置to时,传params是无效的,因为path和params是“强绑定”到路由配置的动态段的,只有用name才能让params生效。传params必须用name,或者直接在path里写死参数(比如/user/123)。
动态路由没传参导致404
如果路由配置是/user/:id,但跳转时没传id(比如params: { id: undefined }),vue - router找不到匹配的路由,就会跳404页面(如果配置了的话),所以动态路由的参数必须传!
query参数刷新后消失?
正常情况下,query参数在url里,刷新不会丢,但如果你的项目用了Hash模式(url带#),且服务器没正确配置,或者参数是通过params传的(但没走动态路由),可能出现刷新丢参,这种情况要么改用query,要么把参数存在Vuex或sessionStorage里。
混淆路由守卫里的to
在路由守卫(比如beforeRouteEnter、beforeEach)里,也有个to参数,这个to是目标路由对象(包含目标路由的path、name、params、query等),和跳转时用的to(配置项)不是一回事,比如在全局守卫里判断目标路由是否需要权限:
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isLogin()) {
next('/login'); // 如果目标路由需要权限且没登录,跳登录页
} else {
next();
}
});
这里的to是目标路由的信息对象,用来做权限判断很方便。
实战中to的灵活运用场景?
光懂理论不够,看几个实战场景里to咋发挥作用:
多语言路由跳转
项目做多语言时,路由可能带locale参数(比如/en/user、/zh/user),用to的对象形式传params:
<router - link
:to="{
name: 'User',
params: { locale: $i18n.locale, id: 123 }
}"
>User Page</router - link>
路由配置对应/:locale/user/:id,这样切换语言时,路由能自动带上当前语言标识。
权限控制后动态跳转
用户登录后,根据角色跳不同页面:
handleLogin() {
const userRole = this.getUserRole(); // 假设拿到角色是admin或user
let target = '';
if (userRole === 'admin') {
target = { name: 'AdminDashboard' };
} else {
target = { name: 'UserCenter' };
}
this.$router.push(target); // 根据角色动态生成to的目标
}
列表项跳详情页(带参)
商品列表页,点击某件商品跳详情页,传商品ID:
<template>
<div v - for="product in productList" :key="product.id">
<router - link
:to="{
name: 'ProductDetail',
params: { id: product.id },
query: { source: 'list' }
}"
>{{ product.name }}</router - link>
</div>
</template>
详情页里用this.$route.params.id拿商品ID,用this.$route.query.source判断用户是从列表还是其他地方进来的,方便做埋点或页面逻辑区分。
说到底,vue - router里的to就是“告诉路由去哪”的关键配置,不管是声明式还是编程式导航,把to的用法、传参逻辑、避坑点吃透,路由跳转这块就稳了,平时写代码时,多结合场景选对to的形式(字符串还是对象)、用好name和params/query的搭配,维护起来更省心,要是碰到问题,先检查to的配置是否和路由规则匹配,参数有没有传对,基本能解决90%的路由跳转bug~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网



