Code前端首页关于Code前端联系我们

一、to在vue router里扮演啥角色?

terry 10小时前 阅读数 13 #Vue
文章标签 vue router;to

做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.idthis.$route.query.from拿到参数。

命名路由的优势

前面提到用name而不是path,好处是路由路径变化时,只要name不变,代码不用改,比如路由配置从path: '/product'改成path: '/goods',只要name: 'ProductDetail'还在,所有用name跳转的地方都不用动,维护性拉满。

to里传参有啥讲究?

用to传参时,paramsquery是最常用的两种方式,但它们的作用、显示方式、是否必填完全不同,得搞清楚区别:

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无效的,因为pathparams是“强绑定”到路由配置的动态段的,只有用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

在路由守卫(比如beforeRouteEnterbeforeEach)里,也有个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前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门