svg-symbol引用方法

  • 【序】今天想為vue封裝一個(gè)可以通過(guò)name就生成一個(gè)icon的組件,平時(shí)我們都是通過(guò)class來(lái)添加一個(gè)字體icon顽铸,但是看到ant-design-vue 中是使用的svg-icon的垫竞,并且配合阿里的iconfont庫(kù)迅耘,使用起來(lái)非常方便酗电,令我心動(dòng),讓我們一起研究一下這個(gè)組件是怎么做到的典徊。
問題一
  • 【疑惑】:為什么要使用svg的圖片格式?
  • 【解答】:
    常用的兩種icon的用法優(yōu)缺點(diǎn)對(duì)比:
font-class
  1. 兼容性良好恩够,支持ie8+卒落,及所有現(xiàn)代瀏覽器。
  2. 相比于unicode語(yǔ)意明確蜂桶,書寫更直觀儡毕。可以很容易分辨這個(gè)icon是什么。
  3. 因?yàn)槭褂胏lass來(lái)定義圖標(biāo)腰湾,所以當(dāng)要替換圖標(biāo)時(shí)雷恃,只需要修改class里面的unicode引用。
  4. 不過(guò)因?yàn)楸举|(zhì)上還是使用的字體费坊,所以多色圖標(biāo)還是不支持的倒槐。
svg
  1. 支持多色圖標(biāo)了,不再受單色限制附井。
  2. 通過(guò)一些技巧讨越,支持像字體那樣,通過(guò)font-size,color來(lái)調(diào)整樣式永毅。
  3. 兼容性較差把跨,支持 ie9+,及現(xiàn)代瀏覽器。
  4. 瀏覽器渲染svg的性能一般沼死,還不如png着逐。
  5. 方便做高性能的動(dòng)畫效果

總結(jié)起來(lái):
沒有動(dòng)畫需求,沒有多色圖標(biāo)的需求意蛀,還是使用font-class會(huì)更好耸别,反之使用svg更好

問題二
  • 【疑惑】:怎么樣引入svg的項(xiàng)目呢?
  • 【解惑】:
  1. 在阿里iconfont中創(chuàng)建一個(gè)項(xiàng)目浸间,并收藏一些icon
    a. 進(jìn)入到一個(gè)icon項(xiàng)目中后屯吊,將需要的icon添加到項(xiàng)目中


    image.png

    b. 點(diǎn)擊右上角


    image.png

    c. 添加到項(xiàng)目
    image.png
  2. 進(jìn)入到自己的項(xiàng)目
    a. 打開自己收藏的項(xiàng)目


    image.png

    b. 生成js導(dǎo)入鏈接


    image.png

    好的,現(xiàn)在就得到了該項(xiàng)目中所有收藏的icon的js項(xiàng)目了猖吴,接下來(lái)我們就可以將該js引入到項(xiàng)目中烁挟!
  3. 引入自己的項(xiàng)目
    a. 最簡(jiǎn)單的辦法就是生成一個(gè)script標(biāo)簽,并將地址賦值給src
    我們可以在public/index.html中直接添加
    b. 本地引入兜看,將地址放到瀏覽器地址欄就能夠得到這段js的內(nèi)容锥咸,將它復(fù)制到一個(gè)本地文件
    然后給一個(gè)plugin,require這一段代碼就可以了
    c. 接下來(lái)可以在component下的任意位置寫一個(gè),并將#icon-xxx中的icon-xxx替換成你需要的icon名即可

<svg class="icon" aria-hidden="true">
    <use xlink:href="#icon-xxx"></use>
</svg>
問題三
  • 【疑惑】:阿里iconfont引入的原理是什么细移?
  • 【解惑】:我們將這段js的原理拆開來(lái)看:
!function(t){var l,h,c,a,p,C,i,d=`
<svg><symbol id="icon-gengduo" viewBox="0 0 1024 1024"></symbol></svg>
`,o=(l=document.getElementsByTagName("script"))[l.length-1].getAttribute("data-injectcss");
if(o&&!t.__iconfont__svg__cssinject__){t.__iconfont__svg__cssinject__=!0;
try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}
catch(t){console&&console.log(t)}}function L(){C||(C=!0,a())}h=function(){var t,l,h,c,a,p=document.createElement("div");p.innerHTML=d,d=null,(t=p.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",l=t,(h=document.body).firstChild?(c=l,(a=h.firstChild).parentNode.insertBefore(c,a)):h.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(c=function(){document.removeEventListener("DOMContentLoaded",c,!1),h()},document.addEventListener("DOMContentLoaded",c,!1)):document.attachEvent&&(a=h,p=t.document,C=!1,(i=function(){try{p.documentElement.doScroll("left")}catch(t){return void setTimeout(i,50)}L()})(),p.onreadystatechange=function(){"complete"==p.readyState&&(p.onreadystatechange=null,L())})}(window);

建議復(fù)制到IDE中格式化后再看[dog/]
總的來(lái)說(shuō)主要最關(guān)鍵的有兩部分:

  1. 給body內(nèi)部的最頂上添加一個(gè)svg元素
  2. 給svg元素添加上style搏予,style給position:absolute 并且隱藏起來(lái)
    其它的就是這段腳本的執(zhí)行時(shí)機(jī),再dom加載完成

如果腳本加載完畢后此時(shí)你的dom元素大概是這樣的:

<body>
  <div>
    <svg style="aria-hidden:true;position:absolute;width:0;height:0;overflow:hidden">
      <symbol id="icon-gengduo" viewBox="0 0 1024 1024"></symbol>
    </svg>
</div>
</body>

在使用時(shí)你在任意位置使用dom就是這個(gè)樣子

<body>
  <div>
    <svg style="aria-hidden:true;position:absolute;width:0;height:0;overflow:hidden">
      <symbol id="icon-gengduo" viewBox="0 0 1024 1024"></symbol>
    </svg>

    <svg class="icon" aria-hidden="true">
      <use xlink:href="#icon-gengduo"></use>
    </svg>
</div>
</body>

總結(jié):其中原理就是當(dāng)svg脫離文檔流后symbol就能夠在任意位置被svg進(jìn)行引用弧轧,多么奇妙的技巧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末雪侥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子精绎,更是在濱河造成了極大的恐慌速缨,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件代乃,死亡現(xiàn)場(chǎng)離奇詭異旬牲,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門原茅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吭历,“玉大人,你說(shuō)我怎么就攤上這事擂橘∩吻” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵贝室,是天一觀的道長(zhǎng)契讲。 經(jīng)常有香客問我,道長(zhǎng)滑频,這世上最難降的妖魔是什么捡偏? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮峡迷,結(jié)果婚禮上银伟,老公的妹妹穿的比我還像新娘。我一直安慰自己绘搞,他們只是感情好彤避,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著夯辖,像睡著了一般琉预。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒿褂,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天圆米,我揣著相機(jī)與錄音,去河邊找鬼啄栓。 笑死娄帖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的昙楚。 我是一名探鬼主播近速,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼堪旧!你這毒婦竟也來(lái)了削葱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤淳梦,失蹤者是張志新(化名)和其女友劉穎佩耳,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谭跨,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了螃宙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛮瞄。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖谆扎,靈堂內(nèi)的尸體忽然破棺而出挂捅,到底是詐尸還是另有隱情,我是刑警寧澤堂湖,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布闲先,位于F島的核電站,受9級(jí)特大地震影響无蜂,放射性物質(zhì)發(fā)生泄漏伺糠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一斥季、第九天 我趴在偏房一處隱蔽的房頂上張望训桶。 院中可真熱鬧,春花似錦酣倾、人聲如沸舵揭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)午绳。三九已至,卻和暖如春映之,著一層夾襖步出監(jiān)牢的瞬間拦焚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工惕医, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留耕漱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓抬伺,卻偏偏與公主長(zhǎng)得像螟够,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子峡钓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354