封裝svg字體圖標(biāo)

前言

在做前端后臺(tái)項(xiàng)目的時(shí)候經(jīng)常會(huì)用到很多 icon 圖標(biāo)迫肖,剛開(kāi)始還好,但隨著項(xiàng)目的不斷迭代,每次修改添加圖標(biāo)會(huì)變得很麻煩牺汤,而且總覺(jué)得不夠優(yōu)雅,于是開(kāi)始琢磨著有啥簡(jiǎn)單方便的工作流呢?

icon演變史

  • 煉氣期:雪碧圖image sprite,所謂的雪碧圖惋增,就是將多個(gè)圖片合成一個(gè)圖片,然后利用 css 的 background-position 定位顯示不同的 icon 圖標(biāo)罗侯。但這個(gè)也有一個(gè)很大的痛點(diǎn)器腋,維護(hù)困難溪猿。每新增一個(gè)圖標(biāo)钩杰,都需要改動(dòng)原始圖片,還可能不小心出錯(cuò)影響到前面定位好的圖片诊县,而且一修改雪碧圖讲弄,圖片緩存就失效了,久而久之你不知道該怎么維護(hù)了依痊。

  • 筑基期:font庫(kù)Font Awesome避除,無(wú)法自定義制定圖標(biāo),只能用別人的胸嘁。

  • 結(jié)丹期:阿里爸爸開(kāi)源圖庫(kù)iconfont瓶摆,三種使用方式:

    • unicode:原理是CSS3特性@font-face,具體使用看文檔性宏!
    • font-class:原理是CSS3特性@font-face群井,具體使用看文檔!
    • symbol:原理是SVG Sprite毫胜,具體使用看下文书斜!
  • 大乘期:上述方式都會(huì),然后酵使,根據(jù)不同的場(chǎng)景使用不同的方式<黾!口渔!

vue-cli3中配置并使用iconfont

  • 第一階段:創(chuàng)建 icon-component 組件
<template>
  <svg class="svg-icon" aria-hidden="true">
    <use :xlink:href="iconName"></use>
  </svg>
</template>

<script>
export default {
  name: 'icon-svg',
  props: {
    iconClass: {
      type: String,
      required: true
    }
  },
  computed: {
    iconName() {
      return `#icon-${this.iconClass}`
    }
  }
}
</script>

<style>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>
//引入svg組件
import IconSvg from '@/components/IconSvg'

//全局注冊(cè)icon-svg
Vue.component('icon-svg', IconSvg)

//在代碼中使用
<icon-svg icon-class="password" />

  • 第二階段:使用 webpack插件svg-sprite-loader样屠,將多個(gè) svg 打包成 svg-sprite。

為什么要打包svg缺脉?

現(xiàn)在所有的 svg-sprite 都在 iconfont.js 里面痪欲,皺巴巴的一塊,很不直觀枪向。最關(guān)鍵是勤揩,無(wú)法做到按需加載,自定義性太差了秘蛔,添加也麻煩陨亡。

svg-sprite-loader和url-loader沖突了怎么辦傍衡?
最安全合理的做法是使用 webpack 的 excludeinclude ,讓svg-sprite-loader只處理你指定文件夾下面的 svg负蠕,url-loaer只處理除此文件夾之外的所以 svg蛙埂,這樣就完美解決了沖突的問(wèn)題。

  • vue.config.js配置如下:
const path = require("path");

function resolve(dir) {
    return path.join(__dirname,dir)
}


module.exports = {
    // 配置webpack
    chainWebpack: (config) => {
        // 配置url-loader: 讓url-loader對(duì)src/assets/svg目錄下的svg圖片不做處理
        config.module.rule("svg").exclude.add(resolve('src/assets/icons/svg')).end();

        // 配置svg-sprite-loader:讓svg-sprite-loader對(duì)src/assets/svg目錄下的svg圖片不做處理
        config.module.rule('icons')
            .test(/\.svg$/)
            .include.add(resolve('src/assets/icons/svg'))
            .end()
            .use('svg-sprite-loader')
            .loader('svg-sprite-loader')
            .options({
                symbolId: 'icon-[name]'
            })
            .end();
    }
}
  • 使用到 webpack 的 require.context遮糖,實(shí)現(xiàn)自動(dòng)導(dǎo)入:

require.context("./test", false, /.test.js$/);
這行代碼就會(huì)去 test 文件夾(不包含子目錄)下面的找所有文件名以 .test.js 結(jié)尾的文件能被 require 的文件绣的。
更直白的說(shuō)就是 我們可以通過(guò)正則匹配引入相應(yīng)的文件模塊。

require.context有三個(gè)參數(shù):

  • directory:說(shuō)明需要檢索的目錄
  • useSubdirectories:是否檢索子目錄
  • regExp: 匹配文件的正則表達(dá)式
import Vue from 'vue'

import IconSvg from "@/components/iconfont/IconSvg.vue";
Vue.component('icon-svg', IconSvg)

// 自動(dòng)導(dǎo)入svg
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req);
  • 具體使用:按需添加svg -> 使用


    按需添加路徑.png
// 直接使用全局組件欲账,iconClass屬性寫(xiě)文件名
<icon-svg iconClass="recharge"/>

第三階段:優(yōu)化
了解svg sprites技術(shù)——移步張大大博客
壓縮SVG——移步張大大博客

#完結(jié)

鳴謝屡江,花褲衩大大、張?chǎng)涡翊蟠笕唬€有我自己惩嘉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市踢故,隨后出現(xiàn)的幾起案子文黎,更是在濱河造成了極大的恐慌,老刑警劉巖殿较,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耸峭,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡淋纲,警方通過(guò)查閱死者的電腦和手機(jī)劳闹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)帚戳,“玉大人玷或,你說(shuō)我怎么就攤上這事∑危” “怎么了偏友?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)对供。 經(jīng)常有香客問(wèn)我位他,道長(zhǎng),這世上最難降的妖魔是什么产场? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任鹅髓,我火速辦了婚禮,結(jié)果婚禮上京景,老公的妹妹穿的比我還像新娘窿冯。我一直安慰自己,他們只是感情好确徙,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布醒串。 她就那樣靜靜地躺著执桌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪芜赌。 梳的紋絲不亂的頭發(fā)上仰挣,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音缠沈,去河邊找鬼膘壶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛洲愤,可吹牛的內(nèi)容都是我干的颓芭。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼禽篱,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼畜伐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起躺率,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎万矾,沒(méi)想到半個(gè)月后悼吱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡良狈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年后添,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片薪丁。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遇西,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出严嗜,到底是詐尸還是另有隱情粱檀,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布漫玄,位于F島的核電站茄蚯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏睦优。R本人自食惡果不足惜渗常,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望汗盘。 院中可真熱鬧皱碘,春花似錦、人聲如沸隐孽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至如失,卻和暖如春绊诲,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背褪贵。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工掂之, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脆丁。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓世舰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親槽卫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子跟压,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容