一天一个 Element 组件 - Link
source link: https://shiningdan.github.io/2020/01/09/%E4%B8%80%E5%A4%A9%E4%B8%80%E4%B8%AA-Element-%E7%BB%84%E4%BB%B6-Link/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
一天一个 Element 组件 - Link
本文是 Element 的组件源码学习系列。
项目源码:ElemeFE/element | GitHub,Tag:v2.13.0
Link 组件使用文档:Link 文字链接
.vue 文件:/packages/link
.scss 文件:[/packages/theme-chalk/link.scss
](https://github.com/ElemeFE/element/blob/dev/packages/theme-chalk/src/link.scss
.d.ts 文件:/types/link.d.ts
el-link
的实现方案,基于原生 <a>
元素
Props
首先我们来看一下 el-link
的 Props,了解使用这个组建的入参:
props: { |
type
字段是用来控制 el-link
组件的样式(主要是颜色),并不影响行为,我们来看一下实现方案:
首先,用户传入 type
属性,type
只会被自动注入到 a
标签的样式类中:
<a |
如果设置了 type
为 success
,则 a
标签会自动添加 el-link--success
的样式类。
我们来看一下 el-link--success
这个样式类做了什么,打开 scss 文件,/packages/theme-chalk/link.scss
定位到这一段相关的代码:
@import "common/var"; |
首先,引入 scss 全局颜色变量,然后定义 el-link
标签使用的 $typeMap
变量,将 type
和 颜色变量映射起来。
其次,遍历映射表 $typeMap
,创建 el-link--#{$type}
样式类。比如当 type
为 success
的时候,就映射到 el-link--success
样式类了。
我们可以通过样式类的定义,大致看到 element 具体做了哪些样式的修改,比如
- 设置了
el-link
标签内的文字颜色color
- 设置鼠标 hover 上去后,文字颜色会有 80% 的透明度
- 设置了
disable
属性后,50% 的透明度 - 设置了
underline
属性后,hover:after
伪元素也要设置边框颜色
所以当 <a>
标签设置了 el-link--success
这个样式类的时候,会应用到 scss 中 type
为 success
的样式。
disable
同理,disable 属性设置后,对应也是修改的 <a>
标签的样式类,以及 href
属性:
<a |
从样式上面来说,输了参考 type
中,有 disable
相关的样式改变外,disabled
还设置了鼠标上移时的鼠标样式反馈:
@include when(disabled) { |
除此以外,还有一个细节:当设置 disabled
的时候,点击这个链接应该是没有跳转行为的。此时,HTML 中的 <a>
标签,应该没有 href
这个属性。经过测试,如果是设置 href=""
,点击 <a>
标签会重复跳转当前页面。
# 点击不会跳转 |
underline
underline
属性的设置,也是反映到 <a>
中 class 的变化。
<a |
el-link
有一个比较细节的地方,就是它的下划线,并没有使用 HTML <a>
的原生 text-decoration: underline
属性,估计是满足不了设计师的设计,太丑了 hhhh。
其实现方案是,创建一个伪元素::after
,通过 position: absolute
设置伪元素和当前 <a>
标签的位置与大小重合。设置 content: ""
设置伪元素没有内容,不会影响 <a>
标签内的内容。最后设置 border-bottom
,来自定义下划线的样式。即 el-link
的下划线,其实是伪元素的 border-bottom
来模拟的。
参考 SCSS 的实现部分:
@include when(underline) { |
slot 与 icon
这两部分放在一起,是因为 slot
与 icon
属性,都是在 <a>
标签的子元素:
<a> |
从这段代码中可以看出来,el-link
支持 icon
属性,也支持默认 slot
,以及具名 slot=icon
,虽然具名 slot
并没有在例子中体现出来。
Template
v-bind="$attrs"
在封装 <a>
的时候,有一个属性大家要注意:
<a v-bind="$attrs"></a> |
通过 v-bind="$attrs"
这种方法,可以将 el-link
中非 props
属性都传给 <a>
标签,这样我们在封装高级组件的时候,特别是封装基础标签的高级组件,不同将该标签的每一个属性都通过 props
单独设置一遍,这在封装基础 HTML 标签的时候很重要。(PS: 为什么 el-button
没有设置 v-bind="$attrs"
呢?我暂时没想出来,大家知道的,非常欢迎在下面留言,我会补充到文章里的~)
click 事件
<template> |
当设置了 disabled
属性,或者没有设置 href
属性的时候,我们可以通过设置 el-link
的 click
事件,来监听 a
标签的点击事件。
CSS 相关的源码解读,之后再补充
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK