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

Vue Router的router-link该怎么用?常见问题有哪些?

terry 9小时前 阅读数 11 #Vue
文章标签 link

很多刚接触Vue.js做前端路由跳转的同学,对router-link组件肯定又好奇又有点懵——它和普通a标签有啥区别?什么时候该用它?碰到样式不生效、跳转异常这些问题咋解决?今天就围绕router-link,把用法、特性、排坑技巧一次性聊透。

router-link和a标签核心区别是啥?

很多人初学的时候,会想“既然都是跳转链接,直接用a标签不行吗?”还真不行,得先搞懂前端路由的逻辑,Vue项目里用Vue Router做单页应用(SPA),页面切换是不刷新整个页面的,靠的是路由匹配组件渲染。

要是用普通a标签写<a href="/about">关于我们</a>,点击后浏览器会直接发起请求,整个页面刷新,这就失去了SPA的优势,而router-link是Vue Router提供的声明式导航组件,它做了这些关键事儿:

  1. 自动适配路由模式:不管你用的是hash模式(URL带#,比如http://xxx/#/home)还是history模式(URL像普通网页,http://xxx/home),router-link会自动生成对应的链接格式,不用你手动判断。
  2. 处理“激活状态”:当当前路由和router-link指向的路由匹配时,它会自动给元素加active-class(默认是router-link-active),方便做选中样式,比如导航栏高亮,普通a标签得自己写JS判断路由来加样式,麻烦多了。
  3. 阻止默认跳转:点击router-link时,它内部会调用router.push(或replace等)方法,走前端路由逻辑,不会触发浏览器的页面刷新。

router-link最基础的用法有哪些?

先从最常用的to属性说起,它决定了要跳转到哪个路由。

to属性的两种写法

  • 字符串路径:适合简单的静态路由,比如路由配置里有{ path: '/news', component: News },那router-link可以写:
    <router-link to="/news">新闻页</router-link>
  • 对象语法:对付动态路由、命名路由更灵活,比如路由配置是{ name: 'Article', path: '/article/:id', component: Article },用name匹配(避免路径硬编码),还能传参数:
    <router-link :to="{ 
      name: 'Article', 
      params: { id: 1001 }, // 动态路由参数
      query: { tab: 'comment' } // 问号后的查询参数
    }">查看文章</router-link>

    这里params对应动态路由的idquery是查询参数,最终URL会变成/article/1001?tab=comment`。

控制跳转行为的属性

  • replace:默认点击router-link是用router.push(往历史记录栈里加一条),加了replace后,会变成router.replace(替换当前历史记录),比如从A页跳到B页,用replace的话,返回时会跳过A页,写法:<router-link to="/contact" replace>联系我们</router-link>
  • tag:指定router-link渲染成什么HTML标签,默认是<a>标签,要是想改成按钮样式的<button>,可以写<router-link to="/login" tag="button">登录</router-link>,不过Vue Router 4之后更推荐用v-slot自定义渲染,后面讲进阶的时候细说。

激活样式相关

默认情况下,当路由匹配时,router-link会加router-link-active类名(全局配置里的activeClass),如果想自定义类名,用active-class属性:

<router-link to="/product" active-class="my-active">产品页</router-link>

但要注意精准匹配问题:比如你有/user/user/info两个路由,点/user/info时,/user的router-link也会被激活(因为是包含匹配),这时候得用exact属性或者exact-active-class来做精准匹配:

<router-link to="/user" exact active-class="exact-active">用户主页</router-link>

加了exact后,只有当路由完全等于/user时才会激活这个link。

怎么给router-link加自定义样式?

导航栏选中态、不同页面的链接高亮,是前端常见需求,这里分两种情况:默认激活类名和自定义类名,还有Scoped样式下的处理。

用默认激活类名写样式

Vue Router默认给激活的router-link加router-link-active类,精准匹配加router-link-exact-active,所以可以直接写CSS:

.router-link-active {
  color: red; /* 选中时变红 */
  border-bottom: 2px solid red;
}

如果项目里用了CSS预处理器(比如Sass),嵌套写也没问题。

自定义active-class

前面讲过用active-class指定类名,

<router-link to="/blog" active-class="blog-active">博客</router-link>

然后CSS里写:

.blog-active {
  /* 自己的样式逻辑 */
}

Scoped样式下的坑

Vue组件里<style scoped>的样式是作用域隔离的,router-link渲染的元素可能不在当前组件作用域内(比如在App.vue里写的导航,被其他组件复用),这时候样式不生效,解决办法有两个:

  • 去掉scoped,把导航样式放到全局CSS里(不太推荐,容易污染);
  • 深度选择器,比如Sass里的>>>或者::v-deep
    <style scoped>
    .nav-wrapper ::v-deep .blog-active {
      color: blue;
    }
    </style>

碰到router-link跳转没反应?先查这几点!

新手最头疼的就是“点了没反应”,得一步步排查:

路由配置是否匹配?

先看to属性写的路径,和router/index.js里的路由配置是否对应,比如路由配的是path: '/goods',你写to="/good"(少了s),肯定匹配不上,如果用命名路由(name),得确保路由配置里有name: 'Goods'这一项,否则对象语法里的name找不到对应路由。

动态路由参数传对了吗?

如果是动态路由(比如path: '/item/:id'),用对象语法时params必须传对应的id,否则路由解析会出错。

<!-- 错误:没传params.id -->
<router-link :to="{ name: 'Item', params: {} }">商品</router-link>
<!-- 正确 -->
<router-link :to="{ name: 'Item', params: { id: 5 } }">商品</router-link>

路由模式是history时,后端配置了吗?

如果用history模式(const router = new VueRouter({ mode: 'history' ... })),部署到服务器后,直接访问http://xxx/about会404,因为后端没配置 fallback,这时候需要后端把所有路由请求都转发到index.html,让前端路由接管,如果没做这个配置,换成hash模式临时测试下,看跳转是否正常。

是不是被组件缓存影响了?

如果页面用了<keep-alive>缓存组件,路由跳转后组件没重新渲染,可能是因为activated生命周期没处理好,或者路由参数变化时,组件的watch没监听$route,这时候得检查:

export default {
  watch: {
    $route(to, from) {
      // 路由变化时执行数据刷新逻辑
      this.fetchData(to.params.id);
    }
  }
}

进阶:router-link的v-slot怎么玩?

Vue Router 2.6+支持用v-slot(插槽)来自定义router-link的渲染,灵活度拉满,比如不想渲染成a标签,想改成button,同时保留路由功能;或者给a标签加自定义属性。

基础插槽用法

router-link的默认插槽会暴露一些属性,比如href(生成的链接)、navigate(点击事件的处理函数),基本写法:

<router-link
  to="/cart"
  v-slot="{ href, navigate }"
>
  <button :href="href" @click="navigate">
    购物车(自定义按钮)
  </button>
</router-link>

这样点击按钮就会触发路由跳转,同时href也正确设置。

控制激活状态

插槽里还能拿到isActive(是否匹配当前路由)、isExactActive(是否精准匹配),用来自己控制样式:

<router-link
  to="/order"
  v-slot="{ isActive, navigate }"
>
  <a 
    @click="navigate" 
    :class="{ 'order-active': isActive }"
  >
    订单页
  </a>
</router-link>
<style>
.order-active {
  color: green;
}
</style>

结合Vue Router 4的变化

Vue Router 4里,router-link的插槽更强大,还能处理aria-current等可访问性属性。

<router-link
  to="/help"
  v-slot="{ isActive, href, navigate }"
>
  <a 
    :href="href" 
    @click="navigate" 
    :aria-current="isActive ? 'page' : null"
  >
    帮助中心
  </a>
</router-link>

这样对屏幕阅读器更友好,符合无障碍访问标准。

router-link的学习节奏

刚入门时,先把to属性的两种写法、active-classreplace这些基础属性玩熟,能搞定大部分导航需求;碰到样式不生效、跳转失败,按照“路由配置→参数传递→模式兼容→组件缓存”的顺序排查;等对Vue Router有一定理解后,再去折腾v-slot自定义渲染,实现更灵活的交互。

router-link是为了解决SPA导航的“无痛跳转 + 状态管理”问题,和传统a标签的区别本质是前端路由和后端路由的区别,把这些逻辑理顺,不管是写博客导航、电商页面跳转,还是复杂的后台管理系统菜单,都能游刃有余~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门