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 结构(浏览器会自动修正,导致样式 / 行为异常)。
相关推荐
DEMO派15 小时前
前端javascript如何实现阅读位置记忆【可运行源码】
前端
苏打水com15 小时前
第十七篇:Day49-51 前端工程化进阶——从“手动”到“自动化”(对标职场“提效降本”需求)
前端·javascript·css·vue.js·html
文心快码BaiduComate15 小时前
Comate强力赋能:「趣绘像素岛」从体验泥潭到高性能可用的蜕变之路
前端·后端·程序员
『 时光荏苒 』15 小时前
使用Vue播放M3U8视频流的方法
前端·javascript·vue.js
Apifox15 小时前
Apifox + AI:接口自动化测试的智能化实践
前端·后端·测试
Tjohn915 小时前
前后端分离项目(Vue-SpringBoot)迁移记录
前端·vue.js·spring boot
CaoLv15 小时前
无需后端!用 React + WebLLM 把大模型装进浏览器,手撸一个“有脾气”的 AI 机器人 🤖
前端
消防大队VUE支队15 小时前
🗓️ 2262年将有两个春节!作为前端的你,日历控件真的写对了吗?
前端·javascript
鸭蛋超人不会飞15 小时前
axios简易封装,适配H5开发
前端·javascript·vue.js
风止何安啊15 小时前
从 “翻页书” 到 “魔术盒”:React 路由凭啥如此丝滑?
前端·react.js·面试