router-link的custom模式

router-link的custom模式

vue项目vue-router中的router-link路由负责管理页面的呈现,今天介绍router-link的custom模式。

什么是 custom模式?

custom 是 router-link 的高级配置属性,启用后会:

  1. 取消默认a标签渲染,允许开发者使用任意 DOM 元素(如 <button><div><li> 等)作为导航容器;
  2. 通过插槽(v-slot)暴露路由核心状态(激活状态、跳转方法),让开发者手动控制导航逻辑;
  3. 保留 Vue Router 原生功能(如无刷新跳转、路由守卫触发、历史记录管理)。

简单来说,custom 模式允许自定义,让导航组件既符合设计需求,又不丢失路由特性。

插槽暴露的关键属性

启用 custom 模式后,router-link 会通过作用域插槽暴露 4 个核心属性,这是实现自定义导航的基础:

属性名 类型 说明
navigate 函数 手动触发路由跳转(替代默认 <a> 标签的点击行为,支持无刷新跳转)
isActive 布尔值 模糊匹配激活:目标路径是当前路径的子集时为 true(例:/user 匹配 /user/123
isExactActive 布尔值 精确匹配激活:目标路径与当前路径完全一致时为 true(例:/user 仅匹配 /user
href 字符串 生成的完整 URL(如 /home 对应 #/home,可用于自定义元素的 href 属性)

navigate 负责跳转逻辑,isActive/isExactActive 控制激活状态,两者结合就能实现完全自定义的导航组件。

基础用法

语法结构

vue 复制代码
<router-link
  to="/target-path"  <!-- 跳转目标(与普通 router-link 一致) -->
  custom             <!-- 启用自定义模式 -->
  v-slot="{ isActive, isExactActive, navigate }"  <!-- 解构插槽属性 -->
>
  <!-- 自定义导航元素(任意 DOM 结构) -->
  <div 
    class="custom-link"
    :class="{ 
      'active': isActive,        // 模糊匹配激活样式
      'exact-active': isExactActive  // 精确匹配激活样式
    }"
    @click="navigate"  <!-- 手动绑定跳转事件 -->
  >
    自定义导航
  </div>
</router-link>

关键说明

  1. 必须手动通过 @click="navigate" 触发跳转,否则点击元素不会生效;
  2. 激活样式需通过 isActive/isExactActive 手动绑定,默认 active-class 属性失效;
  3. 支持 replaceappend 等普通 router-link 支持的属性(例:replace 跳转不添加历史记录)。

官方的AppLink组件写法

html 复制代码
<script setup>
import { computed } from 'vue'
import { RouterLink } from 'vue-router'

defineOptions({
  inheritAttrs: false,
})

const props = defineProps({
  // 如果使用 TypeScript,请添加 @ts-ignore
  ...RouterLink.props,
  inactiveClass: String,
})

const isExternalLink = computed(() => {
  return typeof props.to === 'string' && props.to.startsWith('http')
})
</script>

<template>
  <a v-if="isExternalLink" v-bind="$attrs" :href="to" target="_blank">
    <slot />
  </a>
  <router-link
    v-else
    v-bind="$props"
    custom
    v-slot="{ isActive, href, navigate }"
  >
    <a
      v-bind="$attrs"
      :href="href"
      @click="navigate"
      :class="isActive ? activeClass : inactiveClass"
    >
      <slot />
    </a>
  </router-link>
</template>

封装后优势:一个 组件搞定所有导航需求:

传入 to="http://xxx"(外部链接):自动渲染原生 <a> 标签,带 target="_blank" 新窗口打开;

传入 to="/about"(内部路由):自动用 router-link 实现无刷新跳转;

统一使用 ,降低代码冗余。

VueRouter中的AppLink

小问题

是否可以将router-link包含在a标签内?

不可以

  1. <a> 是原生导航标签,点击会触发浏览器默认跳转(刷新页面或跳转到新 URL);
    是 Vue Router 封装的路由导航组件,核心作用是「无刷新跳转内部路由」。
    两者嵌套后,点击时会同时触发 <a> 的原生跳转和 的路由跳转,导致跳转行为混乱(可能刷新页面,失去 Vue Router 的无刷新优势)。
    DOM 结构不合理:
  2. 原生 HTML 中,<a> 标签是「内联元素」,且不建议嵌套其他可交互元素(尤其是另一个导航元素);
    本质是组件,渲染后会生成 DOM 元素(默认是 <a> ,custom 模式下是自定义元素),嵌套后会出现「<a> 包含 <a>」的非法 DOM 结构(浏览器会自动修正,导致样式 / 行为异常)。
相关推荐
4***V20223 分钟前
Vue3响应式原理详解
开发语言·javascript·ecmascript
常乐我净61630 分钟前
十、路由和导航
前端
Tonychen30 分钟前
TypeScript 里 infer 常见用法
前端·typescript
米诺zuo31 分钟前
MUI sx prop 中的响应式适配
前端
周尛先森32 分钟前
都React 19了,他到底带来了什么?
前端
洞窝技术37 分钟前
一键屏蔽某国IP访问实战
前端·nginx·node.js
fruge1 小时前
前端自动化脚本:用 Node.js 写批量处理工具(图片压缩、文件重命名)
前端·node.js·自动化
Jolyne_1 小时前
antd Image base64缓存 + loading 态优化方案
前端
BINGCHN1 小时前
NSSCTF每日一练 SWPUCTF2021 include--web
android·前端·android studio