這是我參與8月更文挑戰的第5天,活動詳情查看:8月更文挑戰javascript
本文將深刻分析組件 Icon
源碼,剖析其實現原理,耐心讀完,相信會對您有所幫助。 組件文檔 Iconcss
packages/icon/src/icon.vue
文件是組件源碼實現。 github源碼 icon.vuehtml
組件 Icon
的源碼應是最簡單的。封裝了字體圖標的使用方法。提供了屬性 name
,用於指定使用的圖標名稱。vue
<template>
<i :class="'el-icon-' + name"></i>
</template>
<script> export default { name: 'ElIcon', props: { name: String } }; </script>
複製代碼
組件使用 <el-icon name="iconName"></el-icon>
等同於 <i class="el-icon-iconName"></i>
,因此使用圖標功能有兩種實現方式。官方更推薦後者也就是直接使用字體圖標。java
在 Icon
組件示例中直接使用了後者,沒有調用el-icon
組件 。node
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
複製代碼
支持圖標功能的其餘組件內部實現大多使用字體圖標方式,而不是調用el-icon
組件,下面以圖標按鈕爲例。git
// 圖標按鈕 使用方式
<el-button type="primary" icon="el-icon-search">搜索</el-button>
// button 源碼 packages\button\src\button.vue
<template> <button class="el-button" > ... <i class="el-icon-loading" v-if="loading"></i> <i :class="icon" v-if="icon && !loading"></i> ... </button> </template>
複製代碼
用於存放字體圖標使用字體文件。github
element-icons.ttf
是 TrueType格式的字體文件。 Windows和Mac上常見的字體格式,是一種原始格式,所以它並無爲網頁進行優化處理。
element-icons.woff
是 Web Open Font 的字體文件是一個開放的TrueType/OpenType的壓縮版,同時支持元數據包的分離。 Web字體中最佳格式,針對網頁進行特殊優化。web
組件樣式源碼 packages\theme-chalk\src\icon.scss
首先自定義圖標字體庫。chrome
// CSS @規則 指定自定義字體
@font-face {
font-family: "element-icons";
src: url("#{$--font-path}/element-icons.woff") format("woff"),/* chrome, firefox */
url("#{$--font-path}/element-icons.ttf") format("truetype"); /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
font-weight: normal;
font-display: $--font-display;
font-style: normal;
}
複製代碼
font-family
: 指定自定義字庫名稱爲 element-icons
。src
:設置字體的加載路徑和格式 [ <url> [ format( <string> ) ]
,經過逗號分隔多個加載路徑和格式。[ <url> [ format( <string> ) ]
: url
指定自定義的字體的存放路徑 ;string
指定自定義的字體的格式,主要用來幫助瀏覽器識別。 變量$--font-path
值爲 fonts
。font-weight
: 定義字體的粗細。 normal
默認值定義標準的字符。font-style
: 定義字體樣式使用斜體、傾斜或正常字體。 normal
默認值正常字體。font-display
:決定了一個@font-face
在不一樣的下載時間和可用時間下是如何展現的。變量 $--font-display
值爲auto
,字體顯示策略由用戶代理定義。經過CSS選擇器,對class
以el-icon-
開始 或者 包含 el-icon-
的元素設置樣式。經過font-family
引用自定義字體font-family: element-icons !important;
。
[class*=" el-icon-"],
[class^="el-icon-"] {
font-family: element-icons !important;
// ...
}
// ...
// margin 左右設置
.el-icon--right {
margin-left: 5px;
}
.el-icon--left {
margin-right: 5px;
}
複製代碼
顯示圖標使用 CSS 僞元素選擇器::before
進行添加,自身的content
屬性是對應的圖標代碼。 ::before
匹配一個虛擬元素,主要被用於爲當前元素增長裝飾性內容的。顯示的內容是其自身的content
屬性,默認是內聯元素。
// 圖標內容設置
.el-icon-iconName:before {
content: "\eXXX";
}
// ...
複製代碼
前文講到腳本 build/bin/iconInit.js
,解析 packages/theme-chalk/src/icon.scss
,提取全部 icon
名字生成 examples/icon.json
圖標集合文件。
// build\bin\iconInit.js
// 遍歷 nodes
nodes.forEach((node) => {
// ...
// node獲取選擇器名稱匹配 .el-icon-iconName:before
var reg = new RegExp(/\.el-icon-([^:]+):before/);
// ...
});
複製代碼
icon.json
在官網入口文件examples\entry.js
中導入,掛載到 Vue.prototype
。 用於Icon圖標
文檔頁生成全部的圖標集合 。
使用 css animation 實現 loading
圖標不停旋轉效果。
.el-icon-loading {
animation: rotating 2s linear infinite;
}
@keyframes rotating {
0% {
transform: rotateZ(0deg);
}
100% {
transform: rotateZ(360deg);
}
}
複製代碼
前文可知使用 gulpfile.js
編譯 scss
文件轉換爲CSS
,通過瀏覽器兼容、格式壓縮,最後生成 packages\theme-chalk\lib\icon.css
。
一圖描述下使用圖標時,發生了什麼。
<i class="el-icon-share"></i>
// 或
<el-icon name="share"></el-icon>
複製代碼