Element Plus Link 链接组件完全指南:属性、下划线模式、图标与安全实践
【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus
本文围绕 Element Plus 官方文档 Link 链接组件 展开,系统讲解el-link的六种类型(type)、下划线显示时机(underline)、禁用状态(disabled)以及图标(icon)用法,并深入源码验证其底层实现与安全边界。读完本文,你将掌握 Link 组件的全部公开 API、从 2.9.9 起的下划线属性迁移方案,以及如何安全地处理href避免 XSS 与开放重定向风险。
组件定位:Element Plus 中的文本超链接
Link 组件(ElLink)是 Element Plus 提供的文本级超链接组件,位于 packages/components/link 目录。它本质上是对原生<a>标签的封装与增强:在保留href、target等原生语义的同时,统一了主题色、禁用态、下划线动效与图标布局,使链接与表单、按钮等其他组件在视觉上保持一致。
从源码看,组件渲染的根节点就是一个原生<a>标签(见 packages/components/link/src/link.vue),因此它继承了原生链接的可访问性、可聚焦性与语义化特性。组件通过 packages/components/link/index.ts 中的withInstall(Link)注册为可全局安装的插件,也支持按需引入。
安全警告:href 渲染与 XSS 防护
官方文档在正文开始前即给出了明确的 Security Warning:href属性会被直接渲染到<a>标签上。如果你传入javascript:alert(1)之类的值或恶意 URL,可能引发XSS(跨站脚本)或开放重定向漏洞。
对应地,packages/components/link/src/link.vue 中正是:href="disabled || !href ? undefined : href"将用户传入的字符串原样绑定到<a>的href上,组件本身不做任何 URL 校验与净化。因此文档强烈建议:在使用前自行校验并净化 URL,示例代码如下:
function sanitizeUrl(url) { const allowedProtocols = ['http:', 'https:'] try { const parsed = new URL(url, window.location.origin) return allowedProtocols.includes(parsed.protocol) ? parsed.href : '#' } catch { return '#' } }该函数只放行http:与https:协议,将其余协议(如javascript:、data:)以及无法解析的非法 URL 一律回退为#,从源头切断脚本执行向量。实践中建议将净化逻辑封装成工具函数,在将用户输入(尤其是来自富文本、评论、配置后台的数据)传给href之前统一调用。
基础用法:六种类型与 target
Link 支持六种预置类型:default、primary、success、warning、danger、info。下面的示例展示了默认类型的真实跳转链接与其余五种类型:
<template> <div> <el-link href="https://element-plus.org" target="_blank">default</el-link> <el-link type="primary">primary</el-link> <el-link type="success">success</el-link> <el-link type="warning">warning</el-link> <el-link type="danger">danger</el-link> <el-link type="info">info</el-link> </div> </template> <style scoped> .el-link { margin-right: 8px; } </style>该示例对应 docs/examples/link/basic.vue。默认类型链接通常用于一般性引用;primary常用于引导用户跳转的重点链接;success/warning/danger/info则适合在结果提示、状态说明等场景中做语义化跳转。
target 属性
target与原生<a>的target语义一致,可取值'_blank' | '_parent' | '_self' | '_top',默认值为_self(当前窗口打开)。上例中的target="_blank"表示在新标签页打开。若需进一步控制新窗口特性(如rel="noopener"),由于组件未暴露rel属性,建议在href为受控的外部链接时,结合业务层的安全策略统一处理。
禁用状态:disabled
通过disabled布尔属性可启用禁用态。禁用后链接将失去点击与跳转能力,鼠标样式变为not-allowed:
<template> <div> <el-link disabled>default</el-link> <el-link type="primary" disabled>primary</el-link> <el-link type="success" disabled>success</el-link> <el-link type="warning" disabled>warning</el-link> <el-link type="danger" disabled>danger</el-link> <el-link type="info" disabled>info</el-link> </div> </template> <style scoped> .el-link { margin-right: 8px; } </style>该示例对应 docs/examples/link/disabled.vue。从源码可以验证禁用态的完整行为链(见 packages/components/link/src/link.vue):
- 类名计算中
ns.is('disabled', props.disabled)会为根元素添加is-disabled类; :href与:target在禁用时都会被置为undefined,即禁用链接不存在可点击的跳转目标;handleClick在disabled时直接忽略,不再向外派发click事件。
这些行为在 packages/components/link/tests/link.test.tsx 中均有测试覆盖:禁用时断言类名包含is-disabled且href属性为undefined。样式层面,禁用链接使用独立的--el-link-disabled-text-color变量着色,并设置cursor: not-allowed(见 packages/theme-chalk/src/link.scss)。
下划线控制:从 boolean 到 always / hover / never 的迁移
新的三值模式(2.9.9+)
自2.9.9版本起,underline支持'always' | 'hover' | 'never'三个字符串取值,默认值为hover(悬停时显示下划线):
<template> <div> <el-link>default</el-link> <el-link underline="always">always</el-link> <el-link underline="hover">hover</el-link> <el-link underline="never">never</el-link> </div> </template> <style scoped> .el-link { margin-right: 8px; } </style>该示例对应 docs/examples/link/underline.vue。三种取值的行为差异如下:
| 取值 | 默认(不传) | 行为 |
|---|---|---|
always | — | 始终显示下划线(根元素带is-underline类) |
hover | 默认值 | 仅悬停时显示下划线(根元素带is-hover-underline类) |
never | — | 任何情况下都不显示下划线 |
boolean 旧写法已废弃(3.0.0 移除)
官方文档明确标注:underline的boolean 取值已废弃(deprecated),并将在3.0.0中移除。如果你的项目版本低于 2.9.9,仍可使用以下旧写法,但建议尽快迁移:
<template> <!-- works before 2.9.9, use 'hover' after, removed in 3.0.0 --> <el-link underline>link</el-link> <!-- works before 2.9.9, use 'never' after, removed in 3.0.0 --> <el-link :underline="false">link</el-link> </template>迁移映射非常直观:underline(true)等价于新的'hover',:underline="false"等价于'never'。
源码级的兼容实现与废弃提示
源码 packages/components/link/src/link.vue 通过useDeprecated在运行时发出废弃警告,指明The underline option (boolean)应替换为'always' | 'hover' | 'never',移除版本为 3.0.0。同时保留布尔兼容逻辑(见 packages/components/link/src/link.vue):
const underline = computed(() => { if (isBoolean(props.underline)) { return props.underline ? 'hover' : 'never' } else return props.underline ?? globalConfig.value?.underline ?? 'hover' })即布尔true被归一化为hover、false被归一化为never,与迁移映射完全一致;未传入时回退到全局配置(config-provider的link.underline)与默认值hover。属性声明(packages/components/link/src/link.ts)中values: [true, false, 'always', 'never', 'hover']也印证了这一过渡形态。
测试文件 packages/components/link/tests/link.test.tsx 完整覆盖了五种取值的类名断言:true仅带is-hover-underline、false不带任何下划线类、always仅带is-underline、hover仅带is-hover-underline、never不带任何下划线类。
样式实现上,下划线并非text-decoration,而是通过::after伪元素模拟(见 packages/theme-chalk/src/link.scss):is-hover-underline在:hover时才显示::after底边线,is-underline则常驻显示。这样既能精确控制颜色(跟随--el-link-hover-text-color变化),又能避免与图标布局互相干扰。
图标:icon 属性与 icon 插槽
Link 支持两种加图标的方式(示例见 docs/examples/link/with-icon.vue):
方式一:icon 属性
通过icon属性传入图标。可以传字符串形式的组件名(需提前全局注册),也可以直接传入一个 SVG Vue 组件:
<template> <div> <el-link :icon="Edit">Edit</el-link> <el-link> Check<el-icon class="el-icon--right"><icon-view /></el-icon> </el-link> </div> </template> <script setup lang="ts"> import { Edit, View as IconView } from '@element-plus/icons-vue' </script>icon的类型声明为IconPropType(string | Component,见 packages/components/link/src/link.ts),并通过 iconPropType 校验。组件内部使用<el-icon>包裹渲染(见 packages/components/link/src/link.vue),因此图标尺寸、颜色与文本自动对齐。
方式二:icon 插槽
如果希望在图标位置渲染自定义内容(而不限于 Element Plus 图标),可以使用icon具名插槽(见 packages/components/link/src/link.vue)。此时插槽内容直接渲染在文本之后,测试 packages/components/link/tests/link.test.tsx 验证了default与icon两个插槽同时渲染的行为。
Element Plus 提供了一套完整的图标库,可在 Icon 图标组件文档 中查阅全部图标名与用法。
完整 API 一览
以下 API 表整理自 docs/en-US/component/link.md,并与 packages/components/link/src/link.ts 中的 props 声明逐项核对。
Attributes
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type | 链接类型 | enum:'primary' \| 'success' \| 'warning' \| 'danger' \| 'info' \| 'default' | default |
| underline | 下划线显示时机 | enum:'always' \| 'hover' \| 'never' \| boolean(boolean 已废弃,3.0.0 移除) | hover |
| disabled | 是否禁用 | boolean | false |
| href | 同原生超链接的href | string | — |
| target | 同原生超链接的target | enum:'_blank' \| '_parent' \| '_self' \| '_top' | _self |
| icon | 图标组件 | string/Component | — |
补充说明:源码中href的默认值为空字符串''(见 packages/components/link/src/link.ts),渲染时会因!href而被置为undefined,因此不传href时<a>上没有该属性,链接不会真正跳转,仅保留点击事件能力。
Slots
| 名称 | 说明 |
|---|---|
| default | 自定义默认内容(链接文本) |
| icon | 自定义图标组件 |
Events
组件还会在非禁用状态下派发原生click事件(事件声明见 packages/components/link/src/link.ts,派发逻辑见 packages/components/link/src/link.vue),测试 packages/components/link/tests/link.test.tsx 验证了可点击与禁用两种场景下的派发行为。监听方式:<el-link @click="handleClick">。
全局配置:通过 config-provider 定制默认值
从源码 packages/components/link/src/link.vue 的useGlobalConfig('link')可以看出,Link 支持通过config-provider全局配置默认的type与underline(对应LinkConfigContext类型,见 packages/components/link/src/link.ts)。当组件未显式传入这两个属性时,会回退到全局配置。例如:
<el-config-provider :link="{ type: 'primary', underline: 'always' }" > <el-link>未显式传参,将使用全局 primary + always</el-link> <el-link type="success" underline="never">显式传参覆盖全局配置</el-link> </el-config-provider>这一机制让团队可以在应用入口统一业务链接的默认样式,避免逐个组件重复声明。关于配置提供者的更多能力,可参考 Config Provider 文档。
小结与最佳实践
总结 Link 组件的关键要点:
- 安全第一:
href原样渲染到<a>,务必先净化 URL(仅允许http:/https:),防止 XSS 与开放重定向; - 语义化类型:六种类型覆盖常规链接与状态提示场景,
target="_blank"用于新窗口打开; - 下划线迁移:2.9.9 起使用
'always' | 'hover' | 'never',boolean 写法(underline/:underline="false")已废弃并将在 3.0.0 移除,迁移映射为true → 'hover'、false → 'never'; - 禁用态完整:禁用后无
href、不派发click,并呈现not-allowed光标与独立配色; - 图标两种姿势:
icon属性适用于 Element Plus 图标,icon插槽可渲染任意自定义内容; - 全局统一:借助
config-provider的link配置批量定制type与underline默认值。
如需查看实时渲染效果,可在 Element Plus 的 Playground(play 目录)中按文档示例快速验证;相关单测(packages/components/link/tests/link.test.tsx)也可作为理解各属性行为的权威参照。
【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考