elementui源碼學(xué)習(xí)仿寫el-link示例詳解
正文
本篇文章記錄仿寫一個(gè)el-link組件細(xì)節(jié),從而有助于大家更好理解餓了么ui對(duì)應(yīng)組件具體工作細(xì)節(jié)。本文是elementui源碼學(xué)習(xí)仿寫系列的又一篇文章,后續(xù)空閑了會(huì)不斷更新并仿寫其他組件。源碼在github上,大家可以拉下來(lái),npm start運(yùn)行跑起來(lái),結(jié)合注釋有助于更好的理解。
github倉(cāng)庫(kù)地址如下:https://github.com/shuirongsh...
組件思考
簡(jiǎn)而言之,el-link組件就是給a標(biāo)簽包了一層,加上一些樣式。故link組件除了擁有a標(biāo)簽的功能,還需要有一些能夠使用的樣式效果。所以,我們仿寫這個(gè)組件標(biāo)簽的時(shí)候主要是復(fù)習(xí)一下傳參的變量和樣式的搭配,從而實(shí)現(xiàn)我們需要的效果
組件的需求
- 給
link組件加上不同類型的鏈接樣式,比如普通樣式、成功樣式、警告樣式、危險(xiǎn)樣式的鏈接樣式 - 給
link組件加上鼠標(biāo)懸浮時(shí)下劃線。封裝組件中使用的是偽元素搭配border-bottom實(shí)現(xiàn)的 - 通過(guò)傳參去控制
link組件什么時(shí)候有下劃線,什么時(shí)候沒(méi)有下劃線 - 另外,也需要考慮組件會(huì)被禁用,禁用時(shí),不能點(diǎn)擊,不能跳轉(zhuǎn),且更換一下樣式效果
- 同時(shí),
link組件跳轉(zhuǎn)鏈接時(shí)的一些操作 - 也要是考慮到
link組件需要搭配小圖標(biāo)去使用(本例中以餓了么icon為例)
組件的效果圖

組件實(shí)現(xiàn)分析
給link組件加上鏈接樣式
這里使用動(dòng)態(tài)class的數(shù)組用法去控制,如下簡(jiǎn)單例子:
// html
<a
:class="[
'myLink',
type
]"
>
// js
props:{
type: String, // 標(biāo)簽顏色的類型
}
// css
.primary { color: #2d8cf0; }
.success { color: #19be6b; }
.warning { color: #f90; }
.danger { color: #ed4014; }由上,比如傳遞的type參數(shù)值為success,那么a標(biāo)簽就會(huì)加上一個(gè)success的類名,這樣的話,就會(huì)找到對(duì)應(yīng)css中的類名,從而呈現(xiàn)相應(yīng)的顏色效果(當(dāng)然type的值在底下css中要有對(duì)應(yīng)的)
給link組件加上鼠標(biāo)懸浮時(shí)下劃線
其實(shí)類似這種,懸浮下劃線,懸浮上劃線,懸浮特殊背景控制。大致可以歸納為在主要dom旁邊加上一個(gè)小東西,都可以考慮使用偽元素
關(guān)于啥是偽元素,這里不贅述
我們看下方的鼠標(biāo)懸浮上劃線和下劃線的效果圖,這個(gè)效果圖就是使用偽元素搭配定位以及border去實(shí)現(xiàn)的

代碼:
// css
span {
font-size: 24px;
position: relative;
}
span:hover::before {
content: "";
position: absolute;
left: 0;
right: 0;
height: 0;
/* 定位控制 */
top: 2px;
border-top: 1px solid red;
}
span:hover::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 0;
/* 定位控制 */
bottom: -2px;
border-bottom: 1px solid red;
}
// html
<span>早上好,程序猿獸們</span>通過(guò)傳參控制是否加上下劃線(即:是否加上這個(gè)下劃線類名)
這里依然是使用動(dòng)態(tài)class的數(shù)組用法,在數(shù)組中書(shū)寫四元表達(dá)式,簡(jiǎn)約代碼如下:
<a
:class="[
'myLink',
hideUnderline ? '' : disabled ? '' : 'underline'
]"
>大意:即不去隱藏下劃線,又不去禁用這個(gè)link組件的時(shí)候,才加上underline類名,才產(chǎn)生下劃線
使用v-bind="$attrs"兜底a標(biāo)簽的其他的未在props中聲明的參數(shù)
<a
:href="disabled ? null : href" rel="external nofollow" rel="external nofollow"
v-bind="$attrs"
>我們知道a標(biāo)簽中有很多原生屬性,如下圖:

這么多a標(biāo)簽的屬性,我們不可能在封裝的組件的時(shí)候,如果把每一個(gè)屬性都在props中聲明,倒是有些麻煩。所以此時(shí)$attr就應(yīng)運(yùn)而生了。關(guān)于$attr和$listener的用法,這里也不贅述,大家只要記得$attr是做參數(shù)屬性兜底的即可。
詳情可看筆者之前寫的文章:http://www.dbjr.com.cn/article/249437.htm
組件需求由于篇幅原因就不贅述了,詳情見(jiàn)代碼中注釋(畢竟這個(gè)組件其實(shí)也挺簡(jiǎn)單的),接下來(lái)上代碼
代碼
演示的話,直接復(fù)制粘貼即可,結(jié)合注釋更好理解。注意my-divider組件是之前封裝的組件。
筆者封裝的組件和官方封裝的組件在一些細(xì)節(jié)的地方可能略有不同,算是多一個(gè)解法思路吧 ^o^
使用代碼
<template>
<div class="box">
<my-divider lineType="dashed" content-position="left"
>五種鏈接樣式</my-divider
>
<my-link>默認(rèn)超鏈接</my-link>
<my-link type="primary">primary超鏈接</my-link>
<my-link type="success">success超鏈接</my-link>
<my-link type="warning">warning超鏈接</my-link>
<my-link type="danger">danger超鏈接</my-link>
<my-divider lineType="dashed" content-position="left"
>是否有下劃線</my-divider
>
<my-link>默認(rèn)有下劃線</my-link>
<my-link hideUnderline>也可隱藏下劃線</my-link>
<my-divider lineType="dashed" content-position="left"
>禁用鏈接樣式</my-divider
>
<my-link disabled>禁用|默認(rèn)超鏈接</my-link>
<my-link type="primary" disabled>禁用|primary超鏈接</my-link>
<my-link type="success" disabled>禁用|success超鏈接</my-link>
<my-link type="warning" disabled>禁用|warning超鏈接</my-link>
<my-link type="danger" disabled>禁用|danger超鏈接</my-link>
<my-divider lineType="dashed" content-position="left"
>添加href和target原生屬性</my-divider
>
<my-link type="primary" rel="external nofollow" >默認(rèn)self跳轉(zhuǎn)</my-link>
<my-link type="success" target="_blank" rel="external nofollow"
>支持原生屬性target等</my-link
>
<my-divider lineType="dashed" content-position="left"
>通過(guò)icon屬性或者直接在默認(rèn)插槽中添加圖標(biāo)</my-divider
>
<my-link type="primary" icon="el-icon-share">默認(rèn)圖標(biāo)在前方</my-link>
<my-link type="success" icon="el-icon-share" back
>back屬性控制圖標(biāo)在后方</my-link
>
<my-link type="primary"
><i class="el-icon-goods"></i>默認(rèn)插槽前方加圖標(biāo)</my-link
>
<my-link type="success"
>默認(rèn)插槽后方加圖標(biāo) <i class="el-icon-goods"></i
></my-link>
<my-divider lineType="dashed" content-position="left"
>綁定事件使用</my-divider
>
<my-link @click="clickThis" type="danger" icon="el-icon-aim"
>點(diǎn)擊這個(gè)哦</my-link
>
</div>
</template>
<script>
export default {
methods: {
clickThis() {
console.log("注意:當(dāng)myLink禁用或有href屬性時(shí),點(diǎn)擊事件失效");
},
},
};
</script>封裝組件代碼
<template>
<!--
hideUnderline ? '' : disabled ? '' : 'underline',
先看hideUnderline是否為true,為true則要隱藏下劃線,即不加underline類名
再看disabled是否為true,為true則禁用,禁用也要隱藏下劃線,即也不加underline類名
若既不隱藏下劃線又不禁用鏈接,則加上underline類名用于顯示下劃線
-->
<a
:href="disabled ? null : href" rel="external nofollow" rel="external nofollow"
:class="[
'myLink',
hideUnderline ? '' : disabled ? '' : 'underline',
type,
disabled ? 'toDisabled' : '',
]"
v-bind="$attrs"
@click="handleClick"
>
<!--
這里加上v-bind="$attrs"是為了傳遞更多的屬性,做一個(gè)參數(shù)兜底的功能效果。因?yàn)閍標(biāo)簽還有其他很多屬性,如:
target、download、type等。props中未聲明的參數(shù),會(huì)被$attr兜底交給a標(biāo)簽使用。故加了v-bind="$attrs"以后,
在外層my-link標(biāo)簽上,我們便可正常使用除props中聲明的屬性了,如使用target原生屬性:<my-link target="_blank" href="xxx" rel="external nofollow" />
-->
<!-- 內(nèi)容區(qū) -->
<span class="aContent" :class="{ spaceC: icon, back: back }">
<i :class="icon" v-if="icon"></i>
<span><slot></slot></span>
</span>
</a>
</template>
<script>
export default {
name: "myLink",
props: {
href: String, // a標(biāo)簽的href屬性,用于跳轉(zhuǎn)
disabled: Boolean, // 是否禁用超鏈接
type: String, // 標(biāo)簽顏色的類型
// 是否隱藏下劃線
hideUnderline: {
type: Boolean,
default: false, // 默認(rèn)不隱藏下劃線,默認(rèn)展示下劃線
},
icon: String, // 使用餓了么UI的小圖標(biāo)
back: Boolean, // 設(shè)置圖標(biāo)在內(nèi)容后方
},
methods: {
handleClick(event) {
// 禁用狀態(tài)下不允許傳遞事件
if (this.disabled) {
return;
}
// 有鏈接了也不允許傳遞事件
if (this.href) {
return;
}
// 沒(méi)有禁用沒(méi)有鏈接,便可正常傳遞事件
this.$emit("click", event);
},
},
};
</script>
<style lang="less" scoped>
// 默認(rèn)樣式
.myLink {
display: inline-block;
cursor: pointer;
font-size: 14px;
font-weight: 500;
color: #666; // 默認(rèn)顏色,當(dāng)然也可以使用type類型的配色
text-decoration: none; // 去除a標(biāo)簽?zāi)J(rèn)的下劃線(不使用自帶的下劃線效果)
position: relative; // 定位搭配偽元素實(shí)現(xiàn)懸浮下劃線效果
margin: 4px;
.aContent {
display: flex;
align-items: center;
}
// 當(dāng)傳的有圖標(biāo)的時(shí)候,把第一個(gè)元素加上一個(gè)右邊距,產(chǎn)生間距
.spaceC > :first-child {
margin-right: 4px;
}
// 控制彈性盒方向,控制圖標(biāo)在后方位置(默認(rèn)前方位置)
.back {
flex-direction: row-reverse;
}
// 注意這里要覆蓋上方spaceC的樣式
.back > :first-child {
margin: 0 0 0 4px;
}
}
// 通過(guò)變量控制是否有這個(gè)underline類名,從而控制是否有下劃線
.underline:hover::after {
// 這樣的話,元素在哪,下劃線就在哪里
content: "";
position: absolute;
left: 0;
right: 0;
height: 0;
bottom: -2px;
// 注意,這里不設(shè)置顏色,就會(huì)跟隨參考定位的元素的顏色了
border-bottom: 1px solid;
}
// 下方的配色是抄iview的
.primary {
color: #2d8cf0;
}
.success {
color: #19be6b;
}
.warning {
color: #f90;
}
.danger {
color: #ed4014;
}
// 通過(guò)透明度模擬禁用的顏色樣式效果,要不然要寫兩份顏色會(huì)稍微麻煩一些
.toDisabled {
opacity: 0.36;
cursor: not-allowed;
}
</style>以上就是elementui源碼學(xué)習(xí)仿寫el-link示例詳解的詳細(xì)內(nèi)容,更多關(guān)于elementui仿寫el-link示例的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue3的路由守衛(wèi)以及登錄狀態(tài)儲(chǔ)存過(guò)程
這篇文章主要介紹了Vue3的路由守衛(wèi)以及登錄狀態(tài)儲(chǔ)存過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Vue 按照創(chuàng)建時(shí)間和當(dāng)前時(shí)間顯示操作(剛剛,幾小時(shí)前,幾天前)
這篇文章主要介紹了Vue 按照創(chuàng)建時(shí)間和當(dāng)前時(shí)間顯示操作(剛剛,幾小時(shí)前,幾天前),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
el-table?表格分頁(yè)序號(hào)問(wèn)題小結(jié)
這篇文章主要介紹了el-table?表格分頁(yè)序號(hào)問(wèn)題小結(jié),本文通過(guò)實(shí)例代碼圖文效果展示給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-04-04
vue2.0學(xué)習(xí)之a(chǎn)xios的封裝與vuex介紹
最近在研究Vuex2.0,搞了好幾天終于有點(diǎn)頭緒了。下面這篇文章主要給大家介紹了關(guān)于vue2.0學(xué)習(xí)之a(chǎn)xios的封裝與vuex的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05
Vue動(dòng)態(tài)樣式幾種常用方法總結(jié)
這篇文章主要給大家介紹了關(guān)于Vue動(dòng)態(tài)樣式幾種常用方法總結(jié)的相關(guān)資料,在我們的前端界面中,很多的地方的樣式都是不確定的狀態(tài),要根據(jù)其他內(nèi)容的變化而變化樣式的,需要的朋友可以參考下2023-08-08
vue將單頁(yè)面改造成多頁(yè)面應(yīng)用的方法
最近領(lǐng)導(dǎo)交我一個(gè)項(xiàng)目是使用 vue-cli 搭建的單頁(yè)面應(yīng)用。下面小編通過(guò)本文給大家介紹vue將單頁(yè)面改造成多頁(yè)面應(yīng)用的方法 ,感興趣的朋友一起看看吧2018-11-11
vue2移動(dòng)端使用vue-qrcode-reader實(shí)現(xiàn)掃一掃功能的步驟
最近在使用vue開(kāi)發(fā)的h5移動(dòng)端想要實(shí)現(xiàn)一個(gè)調(diào)用攝像頭掃描二維碼的功能,所以下面這篇文章主要給大家介紹了關(guān)于vue2移動(dòng)端使用vue-qrcode-reader實(shí)現(xiàn)掃一掃功能的相關(guān)資料,需要的朋友可以參考下2023-06-06

