多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Vue Router 2 的 `<router-link>` 组件完全指南:导航、属性与激活状态原理

Vue Router 2 的 `<router-link>` 组件完全指南:导航、属性与激活状态原理 前端路由【免费下载链接】vue-router The official router for Vue 2项目地址https://gitcode.com/gh_mirrors/vu/vue-router点击查看免费下载router-link是 Vue RouterVue 2中用于驱动用户导航的核心内置组件它把声明式路由链接变成了一个真正的编程组件你只需通过to属性声明目标地址剩下的 href 生成、点击拦截、激活状态计算全部由框架完成。本文以官方文档 docs-gitbook/es/api/router-link.md 为主线结合仓库源码src/components/link.js、src/router.js、src/util/route.js深入拆解其全部属性、激活类的工作机制与底层实现读完你可以熟练驾驭导航菜单高亮、嵌套路由激活、自定义渲染标签等一切与路由链接相关的实战场景。为什么应该用router-link而不是a href官方文档明确指出在启用了 router 的应用中优先使用router-link替代直接手写a href...理由有三点且这三点都能在源码中找到对应支撑hash 模式与 HTML5 history 模式下行为完全一致。切换路由模式、或让 router 在 IE9 下退化为 hash 模式时你不需要改动任何router-link代码。href 的生成逻辑集中在 src/router.js 的createHrefmode hash时返回# fullPath否则返回完整路径再由base拼接模式差异被完全封装。HTML5 history 模式下会拦截 click 事件阻止浏览器整页刷新。这是由 src/components/link.js 导出的guardEvent函数实现的它先放行带修饰键meta/alt/ctrl/shift的点击、已被preventDefault的事件、右键button ! 0以及target_blank的链接其余情况调用e.preventDefault()阻止浏览器默认跳转随后通过router.push/router.replace完成 SPA 内部导航。配置了base选项时无需在to里重复书写 base 前缀。base会在生成 href 时自动拼接见createHref中的base ? cleanPath(base / path) : pathto属性始终写应用内部的相对路径即可。组件属性全解析to声明目标地址必填类型string | Location必填to标识链接的目标路由访问时其值会被内部传给router.push()。字符串和对象描述符Location都支持!-- 字符串 -- router-link tohomeHome/router-link !-- 渲染为 -- a hrefhomeHome/a !-- 使用 v-bind 的 JavaScript 表达式 -- router-link v-bind:tohomeHome/router-link !-- 省略 v-bind 同样合法与其他属性一致 -- router-link :tohomeHome/router-link !-- 与上例等价的对象写法 -- router-link :to{ path: home }Home/router-link !-- 命名路由 -- router-link :to{ name: user, params: { userId: 123 }}User/router-link !-- 携带 query最终地址为 /register?planprivate -- router-link :to{ path: register, query: { plan: private }}Register/router-link从源码看to的类型校验在 src/components/link.js 中定义为[String, Object]且required: true。渲染时组件会调用router.resolve(this.to, current, this.append)src/router.js——resolve内部先经normalizeLocation规范化地址再交给 matcher 匹配出目标 Route最终用createHref生成真实 href并额外返回location、route供其他逻辑使用。replace替换而非压栈类型boolean默认值false置为true后点击将执行router.replace()而非router.push()导航不会在浏览器历史中留下记录router-link :to{ path: /abc} replace/router-link对应实现位于 src/components/link.js 的点击处理器this.replace ? router.replace(location, noop) : router.push(location, noop)。append相对路径基于当前路由拼接类型boolean默认值false置为true时相对路径会追加到当前路径之后。官方示例当前位于/a点击相对链接b——不加append会跳转到/b加append则跳转到/a/brouter-link :to{ path: relative/path} append/router-link该标志在router.resolve中被透传给normalizeLocation(to, current, append, this)src/router.js由 src/util/location.js 完成路径拼接。tag自定义渲染标签类型string默认值a想让router-link渲染成其他标签如li时使用组件仍会监听 click 事件驱动导航router-link to/foo taglifoo/router-link !-- 渲染为 -- lifoo/li源码逻辑在 src/components/link.js若tag a事件与href直接挂在该元素上否则通过findAnchor在默认插槽中递归寻找第一个a子元素把点击监听与href、aria-current合并到那个a上并保留其原有监听器找不到a时才把监听挂到自己身上。需要特别注意的是从源码的告警信息src/components/link.js可以确认tag属性在 Vue Router 4 中已被移除并废弃后续版本应改用v-slot作用域插槽 API本文仓库中的custom与v-slot支持即是为该迁移铺路。active-class激活状态的 CSS 类类型string默认值router-link-active配置链接处于激活状态时应用的 CSS 类。默认值可通过 router 构造选项linkActiveClass全局覆盖。源码中全局值与组件 props 的优先级逻辑见 src/components/link.jsrouter.options.linkActiveClass为空时才回退到router-link-active组件上的activeClass又优先于全局配置。exact强制精确匹配类型boolean默认值false激活类默认采用包含式inclusive匹配router-link to/a只要当前路径以/a开头如/a/xxx或正好等于/a就会获得激活类。其推论是router-link to/会在所有路由下都保持激活需要精确匹配时加上exact!-- 这个链接仅在路径为 / 时激活 -- router-link to/ exact两种匹配的实现差异在 src/util/route.js 中非常清晰精确匹配走isSameRoutesrc/util/route.js比较去尾斜杠后的 path、hash以及深比较 query命名路由则比较 name、params全部相等才算命中包含匹配走isIncludedRoutesrc/util/route.js只要current.path以target.path开头、hash 与 query 满足包含关系即可。event触发导航的事件2.1.0类型string | Arraystring默认值click用于自定义触发导航的事件可传数组监听多个事件。源码中src/components/link.js若传入数组会遍历每个事件名并把同一个handler挂到on对象上。同样地从源码告警可知event属性在 Vue Router 4 中已被移除官方建议迁移到v-slotAPI。exact-active-class精确激活类2.5.0类型string默认值router-link-exact-active配置链接在精确匹配状态下应用的激活类区别于包含式匹配的router-link-active。默认值可通过 router 构造选项linkExactActiveClass全局覆盖优先级规则与active-class完全一致见 src/components/link.js。激活类渲染逻辑的源码级剖析router-link每次渲染时src/components/link.js都会做以下事情调用router.resolve(this.to, current, this.append)得到目标route与href若目标路由存在redirectedFrom即由重定向产生会基于normalizeLocation(route.redirectedFrom)重建一个比较目标确保激活判断针对用户实际写的地址而非重定向后的地址src/components/link.js计算两个布尔值classes[exactActiveClass] isSameRoute(current, compareTarget, this.exactPath)以及classes[activeClass] this.exact ? 精确结果 : isIncludedRoute(current, compareTarget)——这解释了exact属性为什么能收紧包含式匹配精确激活时附带设置aria-current默认值page可用aria-current-value属性修改见 src/components/link.js增强无障碍支持。把激活类应用到包裹元素有些场景希望激活类落在外层元素而非a标签上此时可以渲染router-link为包裹元素并在内部放一个arouter-link tagli to/foo a/foo/a /router-link这样a仍然是真正的链接获得正确的href与点击行为而激活类会施加到外层li上——这正是上节所述findAnchor机制的实际应用组件把导航逻辑交给内层a把 class 留给tag指定的外层标签。该模式常见于 Bootstrap 等需要.active类加在li上的导航菜单场景。从源码延伸与函数式导航的关系router-link的本质是对router.push/router.replace/router.resolve的声明式封装。当你需要编程式导航时如表单提交后跳转可以直接调用这些方法而组件式写法负责把目标地址 激活状态 自定义标签这些 UI 关注点集中管理。仓库中的 examples/named-routes、examples/named-views 等示例都大量使用了router-link的组合形态如需查看组件级单元测试覆盖可参考 test/unit/specs 下的相关用例。理解二者的映射关系有助于你在声明式与命令式导航之间自如切换。小结属性类型默认值作用tostring \| Location必填目标地址内部传给router.push()replacebooleanfalse改用router.replace()不留历史记录appendbooleanfalse相对路径追加到当前路径tagstringa自定义渲染标签active-classstringrouter-link-active包含式激活类可全局linkActiveClass覆盖exactbooleanfalse强制精确匹配激活eventstring \| Arraystringclick触发导航的事件exact-active-classstringrouter-link-exact-active精确激活类可全局linkExactActiveClass覆盖掌握router-link的这些属性与包含式 vs 精确式激活机制再结合对resolve、guardEvent、isSameRoute/isIncludedRoute底层实现的理解你就能精准控制导航高亮、优雅处理嵌套路由的激活边界并为 Vue Router 4 的v-slot迁移做好铺垫。更深层的实现细节可直接阅读 src/components/link.js 与 src/util/route.js。赞分享前端路由【免费下载链接】vue-router The official router for Vue 2项目地址https://gitcode.com/gh_mirrors/vu/vue-router点击查看免费下载相关推荐Vue Router 2 router-link 组件完全指南Props、激活态机制与 v-slot 自定义渲染Vue Router 2 router link 组件完全指南Props、激活态机制与 v slot 自定义渲染 router link 是 Vue Ro前端路由vue-router 2.x 中 router-link 组件完整指南Props、激活类与源码实现解析vue router 2.x 中 router link 组件完整指南Props、激活类与源码实现解析 router link 是 vue router前端路由Vue Router 组件注入完全指南$router / $route 属性与组件内导航守卫Vue Router 组件注入完全指南$router / $route 属性与组件内导航守卫 本文以 Vue RouterVue 2 官方路由本仓库 gh前端路由创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表