一、router link最基础的用法是怎样的?
做Vue项目时,导航栏切换页面、点击列表跳详情页这些场景,都离不开路由导航,vue - router里的router - link是官方推荐的“声明式导航”组件,但新手刚接触时,总会纠结「怎么传参?选中样式咋改?和a标签有啥区别?」…这篇把router - link从基础到进阶的常见问题拆碎了讲,看完不用再对着文档干瞪眼~
router - link核心作用是「生成可跳转的导航链接」,最基础的用法就一个属性——to
,比如做个首页导航:
<router - link to="/home">首页</router - link>
这段代码渲染到页面后,默认是个标签,点它会触发路由跳转,而且是单页应用无刷新跳转(不像普通a标签点了会整页刷新)。
这里要注意几个点:
to
是必填项,值可以是字符串路径(如/home
),也能是对象(后面讲动态传参时会展开);- 默认渲染成标签,想改成按钮、div之类的,加个
tag
属性,比如<router - link tag="button" to="/login">登录</router - link>
,就会渲染成button; - 如果页面里不需要渲染成任何标签(纯逻辑跳转),可以用
v - slot
自定义渲染,但新手阶段先掌握基础用法就行。
动态路由传参该怎么用router - link实现?
实际项目里,“点击用户列表跳详情页”“搜索页带关键词跳转”这些场景,都需要传参,router - link传参分params和query两种方式,用法和场景差别很大,得仔细区分~
用params传参(适合“路径里带参数”的场景)
比如用户详情页的路径是/user/123
(123是用户ID),这种“路径里嵌参数”的场景用params,步骤分两步:
第一步:在路由配置里定义动态段,
const routes = [
{
path: '/user/:id', // 动态段:id
name: 'UserDetail',
component: UserDetail
}
]
第二步:在router - link里用对象语法传参,推荐用name
匹配路由(因为path写死的话不够灵活):
<router - link :to="{ name: 'UserDetail', params: { id: 123 }}">
查看用户123详情
</router - link>
这样点击后,路径会变成/user/123
,详情页里用$route.params.id
就能拿到123。
⚠️ 注意:如果用path
代替name
,比如:to="{ path: '/user/:id', params: { id: 123 }}"
,params会被忽略!所以params传参必须用name匹配路由,或者直接写死路径(但不灵活)。
用query传参(适合“路径后带?xxx = xxx”的场景)
比如搜索页,路径是/search?keyword = vue
,这种“参数跟在路径后”的场景用query,用法更简单,直接在对象里加query
属性:
<router - link :to="{ path: '/search', query: { keyword: 'vue' }}">
搜索Vue相关内容
</router - link>
跳转后路径是/search?keyword = vue
,搜索页用$route.query.keyword
就能拿到参数,query传参的好处是刷新页面参数不会丢(params刷新会丢,除非路由配置里写死),适合做搜索、筛选这类需要保留参数的场景。
怎么给router - link设置选中时的高亮样式?
导航栏“当前页高亮”是刚需,但很多新手第一次做时,样式怎么都不生效,其实router - link自带两个“激活时的类名”,理解清楚就能玩转~
默认的激活类名
router - link有两个默认类名:
router - link - active
:模糊匹配激活(比如父路由和子路由都会激活);router - link - exact - active
:精确匹配激活(只有路径完全一致才会激活)。
比如根路径是,子路由是/about
,当进入/about
时,对应的router - link会有router - link - active
(因为是父路由),但不会有router - link - exact - active
(路径不完全一致)。
自定义类名(局部 + 全局)
如果觉得默认类名不好记,想改成自己的,有两种方式:
局部改:给单个router - link加active - class
或exact - active - class
,
<router - link
to="/home"
active - class="my - active"
exact - active - class="my - exact - active"
>首页</router - link>
全局改:在创建router实例时,配置linkActiveClass
和linkExactActiveClass
,所有router - link都会生效:
const router = createRouter({
history: createWebHistory(),
routes,
linkActiveClass: 'global - active', // 全局模糊匹配类名
linkExactActiveClass: 'global - exact - active' // 全局精确匹配类名
})
什么时候用exact?
回到根路径的例子:如果导航栏有个“首页”对应,还有个“关于我们”对应/about
,当进入/about
时,“首页”的router - link会被模糊激活(因为/about包含/),导致两个导航同时高亮,这显然不对。
这时候给“首页”的router - link加exact
属性,就能精确匹配,只有路径完全等于时才激活:
<router - link to="/" exact>首页</router - link>
导航层级深、有子路由时,父路由的router - link一定要加exact
,否则子路由激活时父路由也会高亮,视觉上很混乱。
router - link和普通a标签有啥核心区别?
很多人刚开始会疑惑:“既然router - link最终渲染成a标签,直接用a标签不行吗?” 还真不行,两者在「导航原理」「用户体验」「路由功能」上差别巨大:
导航原理:单页跳转 vs 多页跳转
router - link是单页应用内的“无刷新跳转”——点击后,Vue只更新页面里变化的部分(比如组件替换),浏览器不会整页刷新,也不会重新请求HTML/CSS/JS资源,体验丝滑。
普通a标签是多页应用的“硬跳转”——点击后浏览器会重新请求目标页面的所有资源(HTML、CSS、JS全重新加载),页面会白屏一下,体验差,而且之前页面的状态(比如表单输入内容)会丢失。
路由守卫:能拦截 vs 不能拦截
router - link点击时,会触发vue - router的导航守卫(比如全局守卫、路由独享守卫),可以在跳转前做权限判断(比如判断用户是否登录,没登录就拦截跳转)。
普通a标签是直接跳转到目标地址,没法用vue - router的守卫拦截,想做权限控制只能自己写JS逻辑(比如给a标签加onclick事件,阻止默认行为后判断),麻烦又容易漏。
SEO友好度:间接支持 vs 直接支持
单页应用(SPA)的SEO天生弱,因为内容是JS渲染,搜索引擎爬虫可能抓不到,但router - link生成的a标签有href属性,爬虫能抓取这个链接,后续结合服务端渲染(SSR)或预渲染,就能让爬虫拿到完整页面内容。
普通a标签的href如果是指向其他域名,爬虫也能抓,但如果是单页应用里的前端路由(比如),和router - link的href作用类似,区别还是在跳转体验上。
做单页应用时,导航必须用router - link;如果是多页应用(比如传统PHP项目),才用a标签。
router - link能结合编程式导航做复杂逻辑吗?
router - link是“声明式导航”(写标签就完成跳转),但实际项目里经常需要“点击后先做逻辑,再跳转”(比如权限判断、埋点统计),这时候可以把router - link和“编程式导航”(比如this.$router.push
)结合起来用~
点击时先做权限判断
后台管理”页面需要登录后才能进,给router - link加个点击事件,判断是否登录:
<router - link to="/admin" @click="checkAuth">后台管理</router - link>
methods: {
checkAuth(event) {
if (!this.isLogin) { // isLogin是判断登录状态的变量
alert('请先登录!');
event.preventDefault(); // 阻止默认跳转行为
return;
}
// 登录了就正常跳转,不用额外处理,因为router - link默认会跳转
}
}
这里的关键是用event.preventDefault()
阻止默认跳转,等逻辑处理完再决定是否放行。
跳转前记录来源路径
比如用户从列表页跳详情页,详情页有个“返回”按钮要回到列表页,可以在router - link点击时,把当前路径存在Vuex或sessionStorage里:
<router - link to="/product/123" @click="saveFromPath">查看商品123</router - link>
methods: {
saveFromPath() {
this.$store.commit('SET_FROM_PATH', this.$route.path);
}
}
详情页的“返回”按钮用编程式导航跳回去:
<button @click="goBack">返回</button>
methods: {
goBack() {
const fromPath = this.$store.state.fromPath;
this.$router.push(fromPath || '/product');
}
}
这种“声明式 + 编程式”的组合,能覆盖更复杂的业务逻辑,比纯声明式或纯编程式更灵活。
嵌套路由里router - link怎么处理层级关系?
做后台管理系统时,经常有“一级导航→二级导航→页面内容”的嵌套结构(比如仪表盘→分析页→实时数据),这时候router - link的层级匹配和active样式很容易出问题,得注意这两点:
路由配置的嵌套结构
先看路由配置(以Vue3为例):
const routes = [
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard,
children: [ // 子路由
{
path: 'analysis', // 注意:路径没加/,是相对父路由的
name: 'Analysis',
component: Analysis
},
{
path: 'monitor',
name: 'Monitor',
component: Monitor
}
]
}
]
父路由Dashboard的组件里,要渲染子路由出口(<router - view>
),子路由的路径是相对于父路由的,所以访问/dashboard/analysis
时,父组件和子组件都会渲染。
router - link的层级匹配
父组件(Dashboard)里的router - link:
<router - link to="/dashboard">仪表盘</router - link>
子组件(Analysis)里的router - link:
<router - link to="analysis">分析页</router - link>
<!-- 这里to用相对路径,等价于to="/dashboard/analysis" -->
当进入/dashboard/analysis
时,父组件的router - link会被模糊激活(因为路径包含/dashboard),所以会有active样式;子组件的router - link会被精确激活,这种“父激活 + 子激活”的效果,正好符合嵌套导航的视觉逻辑(比如一级导航高亮,二级导航也高亮)。
如果不想让父路由在子路由激活时高亮,给父路由的router - link加exact
属性即可,但嵌套导航一般需要父路由保持高亮,所以不用加。
router - link对SEO友好吗?怎么优化?
单页应用(SPA)的SEO一直是痛点——因为页面内容靠JS渲染,搜索引擎爬虫(比如百度、谷歌蜘蛛)可能还没等JS执行完就抓取页面,导致拿到的是空白HTML,收录效果差,但router - link能帮我们做这些优化:
给router - link加合理的href和锚文本
router - link渲染的a标签有href属性,爬虫能抓取这个链接,所以要给每个router - link写清晰的锚文本(Vue入门教程”比“点击这里”好),还可以加title属性辅助爬虫理解:
<router - link to="/article" title="Vue.js入门教程,从基础到实战">Vue入门</router - link>
结合服务端渲染(SSR)或预渲染
如果项目对SEO要求高,纯SPA满足不了,得用服务端渲染(SSR,如Nuxt.js)或预渲染(Prerender SPA Plugin):
- SSR:服务器把Vue组件渲染成HTML再返回给浏览器,爬虫能直接拿到完整内容;
- 预渲染:打包时给每个路由生成对应的静态HTML文件,部署后爬虫访问这些HTML。
这两种方式都需要router - link的href是正确的路由地址,才能让爬虫顺着链接抓取所有页面。
避免使用history模式的404问题
如果用history模式(createWebHistory
),直接访问子路由(比如yourdomain.com/about
)时,服务器可能返回404,因为服务器不知道这个路由对应的HTML,这时候需要服务器配置 fallback( fallback到index.html),保证所有路由请求都能命中SPA入口,同时结合SSR或预渲染解决SEO。
用router - link时常见错误怎么排查?
新手用router - link时,经常遇到“跳转没反应”“样式不生效”“传参丢
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。