<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          web圖標(biāo)的工程化方案

          共 13158字,需瀏覽 27分鐘

           ·

          2021-05-13 21:41

          點(diǎn)擊上方 前端瓶子君,關(guān)注公眾號(hào)

          回復(fù)算法,加入前端編程面試算法每日一題群

          來源:周周醬愛學(xué)習(xí)

          https://juejin.cn/post/6952150039732944910


          如何管理圖標(biāo)是我們?cè)趙eb項(xiàng)目開發(fā)過程中都會(huì)遇到的問題。隨著web技術(shù)的發(fā)展,圖標(biāo)方案也經(jīng)歷了幾個(gè)階段,以下這幾種圖標(biāo)方案也基本能涵蓋web圖標(biāo)使用的歷程。

          image sprite

          最早通過img標(biāo)簽或background-image來引用圖標(biāo),每個(gè)圖標(biāo)單獨(dú)引用,后來為了減少http的請(qǐng)求,提高網(wǎng)站性能,提出sprite的概念,將小的 png 圖片合并到一張圖上,然后根據(jù) background-position 來顯示不同的圖片。

          優(yōu)勢(shì):

          1. 兼容性好
          2. 還原度高

          劣勢(shì):

          1. 同一圖標(biāo)的不同顏色需要設(shè)計(jì)多個(gè)圖片
          2. 新增圖標(biāo)需要重新合成sprite
          3. 由于是位圖,兼容不同分辨率需要多套尺寸

          iconfont

          為了更易于控制圖標(biāo)顏色和大小,并兼容各種設(shè)備屏幕,后來開始出現(xiàn)iconfont方案。iconfont就是圖標(biāo)字體,我們可以像使用普通字體一樣使用它,只要適合字體相關(guān)的CSS屬性都適合字體圖標(biāo),使用font-size和color就可以輕松控制圖標(biāo)的大小和顏色。隨著各種字體圖標(biāo)庫(kù)網(wǎng)站的出現(xiàn),國(guó)外的icomoon.io,或者國(guó)內(nèi)阿里的iconfont.cn,帶來的全套解決方案,使iconfont流行起來。

          優(yōu)勢(shì):

          1. 能夠容易地改變圖標(biāo)的顏色,尺寸
          2. 矢量圖不失真
          3. 兼容所有流行的瀏覽器,在h5和app上都能使用
          4. 替換圖標(biāo)和新增圖標(biāo)也非常簡(jiǎn)單,也不需要考慮圖標(biāo)合并的問題

          劣勢(shì):

          1. 只支持單色圖標(biāo)
          2. 字體渲染,低倍屏下容易出現(xiàn)鋸齒

          引用方式

          iconfont的使用方式也很簡(jiǎn)單,使用 @font-face 引入字體格式,就和使用其他自定義字體一樣。

          @spicons-font-path"./fonts";
          @font-face {
           font-family"spicons";
           srcurl('@{spicons-font-path}/spicons.eot?v=1');
           srcurl('@{spicons-font-path}/spicons.eot?v=1#iefix'format('eot'),
               url('@{spicons-font-path}/spicons.ttf?v=1'format('truetype'),
            url('@{spicons-font-path}/spicons.woff?v=1'format('woff'),
            url('@{spicons-font-path}/spicons.svg?v=1#spicons'format('svg');
          }
          .sp-icon {
           font-family"spicons";
              display: inline-block;
              font-style: normal;
              font-weight: normal;
              font-variant: normal;
              text-transform: none;
              text-rendering: auto;
              line-height1;
              -webkit-font-smoothing: antialiased;
              -moz-osx-font-smoothing: grayscale;
          }
          復(fù)制代碼
          • unicode 引用
          <div class="sp-icon">&#xE001;</div>
          復(fù)制代碼
          • 使用配套生成的樣式
          <link rel="stylesheet" href="./iconfont.css">
          <span class="sp-icon icon-xxx"></span>
          復(fù)制代碼

          工程化方式

          依賴網(wǎng)站生成字體文件,在替換或加圖標(biāo)后需要重新覆蓋項(xiàng)目中的圖標(biāo)css代碼,不夠自動(dòng)化。可以使用工具腳本在本地項(xiàng)目中將SVG文件生成iconfont,更方便地管理項(xiàng)目圖標(biāo)。需要在項(xiàng)目中安裝以下依賴庫(kù)。

          • gulp (自動(dòng)化構(gòu)建工具)
          • gulp-iconfont (使用gulp將svg圖標(biāo)集合創(chuàng)建為 svg/ttf/eot/woff/woff2字體)
          • gulp-iconfont-css (結(jié)合gulp-iconfont生成配套的css樣式)

          gulpfile

          var gulp = require('gulp');
          var iconfont = require('gulp-iconfont');
          var iconfontCss = require('gulp-iconfont-css');

          /** 生成圖標(biāo)字體文件*/
          gulp.task('Iconfont'function({
              return gulp
                  .src(['../src/icons/svg/*.svg'])
                  .pipe(
                      iconfontCss({
                          fontName'spicons'//字體名
                          path'../src/icons/templates/iconFont.less'//模板文件路徑
                          targetPath'../spicons-icons.less',//樣式文件目標(biāo)地址相對(duì)于dest目錄
                          cssClass'sp-icon' //樣式類名
                      })
                  )
                  .pipe(
                      iconfont({
                          fontName'spicons'// required
                          formats: ['ttf''eot''woff''svg']
                      })
                  )
                  .pipe(gulp.dest('../src/styles/iconfont/fonts'));
          });


          gulp.task('default',gulp.series('Iconfont'));
          復(fù)制代碼

          gulp-iconfont-css支持使用自定義的css模板,來組織生成的字體配套樣式,以靈活的方式創(chuàng)建符合項(xiàng)目規(guī)范的樣式命名,引用路徑。

          • less模板
          @spicons-font-path"./fonts";
          @font-face {
           font-family"<%= fontName %>";
           srcurl('@{spicons-font-path}/<%= fontName %>.eot?v=1');
           srcurl('@{spicons-font-path}/<%= fontName %>.eot?v=1#iefix'format('eot'),
               url('@{spicons-font-path}/<%= fontName %>.ttf?v=1'format('truetype'),
            url('@{spicons-font-path}/<%= fontName %>.woff?v=1'format('woff'),
            url('@{spicons-font-path}/<%= fontName %>.svg?v=1#<%= fontName %>'format('svg');
          }

          .<%= cssClass%> {
           font-family"<%= fontName %>";
              display: inline-block;
              font-style: normal;
              font-weight: normal;
              font-variant: normal;
              text-transform: none;
              text-rendering: auto;
              line-height1;
              -webkit-font-smoothing: antialiased;
              -moz-osx-font-smoothing: grayscale;
          }

          <% _.each(glyphsfunction(glyph) { %>@icon-<%= glyph.fileName.replace(/[\d]{1,}([\-])/, "") %>: "\<%= glyph.codePoint %>";
          <% }); %>

          .<%= cssClass%>-char(@icon-variable) {
           content: @@icon-variable;
          }

          .<%= cssClass%>-base-pseudo(@filename, @insert: before) {
           @pseudo-selector: ~":@{insert}";
              @icon-variable: ~"icon-@{filename}";
           &@{pseudo-selector} {
            .<%= cssClass%>-char(@icon-variable);
           }
          }

          <% _.each(glyphsfunction(glyph) { 
              %>.<%= cssClass%>-<%= glyph.fileName.replace(/[\d]{1,}([\-])/, "") %> {
           .<%= cssClass%>-base-pseudo(<%= glyph.fileName.replace(/[\d]{1,}([\-])/, "") %>);
          }
          <% }); %>
          復(fù)制代碼
          • 執(zhí)行構(gòu)建圖標(biāo)命令gulp \--gulpfile build/build-icon.js

          • 生成字體圖標(biāo)以及樣式文件

          微信圖片_20191214224749.png
          • 樣式文件
          微信圖片_20191231153104.png

          svg sprite

          svg意為可縮放矢量圖形,它不會(huì)像位圖一樣因?yàn)榉糯蠖д妫诓煌直媛氏碌谋憩F(xiàn)都一樣清晰。svg其實(shí)很早就出現(xiàn)了,只不過由于兼容性的問題,早前并沒有很好地發(fā)揮出它的價(jià)值,但隨著IE6/7/8退出舞臺(tái), android 4.x 的開始,很多網(wǎng)站都開始使用svg作為圖標(biāo)方案 。github在16年的時(shí)候已經(jīng)使用svg替代iconfont,ant design在 3.9.0 之后,使用了 svg圖標(biāo)替換了原先的 font 圖標(biāo)。

          優(yōu)勢(shì):

          1. 能夠容易地改變圖標(biāo)的顏色,尺寸
          2. 支持彩色圖標(biāo)
          3. 矢量圖不失真
          4. 可讀性好,有利于SEO與無障礙
          5. 渲染效果好,不會(huì)有鋸齒

          劣勢(shì):

          1. 體積相對(duì)于iconfont較大

          引入方式

          1. 使用img、object、embed標(biāo)簽或者作為background背景圖直接引用svg,或者可以合并成雪碧圖,這種方式與png雪碧圖使用方法一樣。
          2. inline svg,svg本身是一個(gè)html標(biāo)簽,可以直接把svg寫入 html中。
          <body>
            <div>
              <svg>....</svg>
            </div>
          </body>
          復(fù)制代碼
          1. 使用 svg中的 symbol,use 元素來制作圖標(biāo)

          標(biāo)記的作用是定義一個(gè)圖像模板,本身不會(huì)輸出任何圖像,可以使用標(biāo)記實(shí)例化它。在實(shí)際項(xiàng)目中我們會(huì)有很多圖標(biāo),將零散的svg合并,每個(gè)圖標(biāo)有唯一的symbol,通過symbol來引用。將symbol定義插入到頁(yè)面body中,然后在需要使用的地方通過引用。將xlink:href設(shè)置為定義的symbol id即可。

          <svg style="display: none;">
           <symbol viewBox="0 0 16 16" id="icon-bell">
            <path fill="#ffa896" d="M14,12 L15.5,12 C15.7761424,12 16,12.2238576 16,12.5 C16,12.7761424 15.7761424,13 15.5,13 L0.5,13 C0.223857625,13 3.38176876e-17,12.7761424 0,12.5 C-3.38176876e-17,12.2238576 0.223857625,12 0.5,12 L0.5,12 L2,12 L2,6 C2,2.6862915 4.6862915,6.08718376e-16 8,0 C11.3137085,-6.08718376e-16 14,2.6862915 14,6 L14,12 Z M3,12 L13,12 L13,6 C13,3.23857625 10.7614237,1 8,1 C5.23857625,1 3,3.23857625 3,6 L3,12 Z M8,16 C6.8954305,16 6,15.1045695 6,14 C7,14 9,14 10,14 C10,15.1045695 9.1045695,16 8,16 Z"></path>
           </symbol>
            <symbol viewBox="0 0 16 16" id="icon-arrow-up">
            <path fill="#ffa896" d="M413.1,327.3l-1.8-2.1l-136-156.5c-4.6-5.3-11.5-8.6-19.2-8.6c-7.7,0-14.6,3.4-19.2,8.6L101,324.9l-2.3,2.6  C97,330,96,333,96,336.2c0,8.7,7.4,15.8,16.6,15.8v0h286.8v0c9.2,0,16.6-7.1,16.6-15.8C416,332.9,414.9,329.8,413.1,327.3z"></path>
           </symbol>
          </svg>
          復(fù)制代碼
          <svg>
           <use xlink:href="#icon-arrow-up"/> 
          </svg>
          <svg>
           <use xlink:href="#icon-bell"/> 
          </svg>
          復(fù)制代碼
          微信圖片_20191215160410.png

          symbol可以寫入到body中,同時(shí)可以使用外鏈引用,不過使用外鏈的方式在IE下兼容性不是很好。

          <svg>
           <use xlink:href="/assets/svg-symbols.svg#icon-arrow-up"/> 
          </svg>
          復(fù)制代碼

          工程化方式

          手動(dòng)中合成引入那一坨 symbol 模板是不方便的,我們需要的是自動(dòng)管理圖標(biāo)。隨著 webpack 打包的成熟,各種 loader的出現(xiàn),為我們提供了成熟的方案。

          • svg-sprite-loader

          針對(duì)所引用的svg文件,svg-sprite-loader會(huì)把你的icon塞到一個(gè)個(gè)symbol中,最終在你的body中嵌入合并后的symbol。

          示例項(xiàng)目使用vue cli 3搭建,vue.config.js相關(guān)配置如下,我們會(huì)將圖標(biāo)文件放在一個(gè)特定的目錄中,針對(duì)該目錄下的文件,會(huì)將默認(rèn)的loader配置排除,使用svg-sprite-loader。

          chainWebpack:config=> {  
                  config.module
                    .rule('svg')
                    .exclude.add(resolve('src/icons'))
                    .end()
                  config.module
                    .rule('icons')
                    .test(/\.svg$/)
                    .include.add(resolve('src/icons'))
                    .end()
                    .use('svg-sprite-loader')
                    .loader('svg-sprite-loader')
                    .options({
                      symbolId'icon-[name]'
                    })
                    .end()
                }
          復(fù)制代碼
          • 批量引入圖標(biāo)文件
          const req = require.context('/src/icons'true, /\.svg$/)
          const requireAll = requireContext => requireContext.keys().map(requireContext)
          requireAll(req)
          復(fù)制代碼
          • 運(yùn)行項(xiàng)目后可以看到body中插入了svg symbol
          微信圖片_20191215163114.png
          • 我們就可以在頁(yè)面中使用這些圖標(biāo)了,同時(shí)可以封裝通用icon調(diào)用組件,將圖標(biāo)name,size,color都作為參數(shù),就能方便控制圖標(biāo)的使用。
          <template>
          <i :style="styles" :class="iconClass">
            <svg class="svg-icon" aria-hidden="true" v-on="$listeners">
              <use :xlink:href="iconName" />
            </svg>
          </i>
          </template>

          <script>
          export default {
            name'SvgIcon',
            props: {
              typeString,
              size: [NumberString],
              colorString,
              className:String
            },
            computed: {
              iconName() {
                return `#icon-${this.type}`
              },
              iconClass() {
                if (this.className) {
                  return 'icon ' + this.className
                } else {
                  return 'icon'
                }
              },
              styles() {
                let style = {}
                if (this.size) {
                  style['font-size'] = `${this.size}px`
                }
                if (this.color) {
                  style.color = this.color
                }
                return style
              },
            },
          }
          </script>
          <style scoped>
          .icon{
            display: inline-block;
            line-height0;
          }
          .svg-icon {
            width1em;
            height1em;
            fill: currentColor;
            overflow: hidden;
            vertical-align: middle;
          }
          </style>
          復(fù)制代碼
          <svg-icon type="bell" size="60" color="#ffa896"/>
          復(fù)制代碼
          微信圖片_20191215163745.png

          小結(jié)

          各方案有利有弊,一套方案不一定能兼容全部場(chǎng)景,這一切都取決于項(xiàng)目實(shí)際情況和瀏覽器的支持情況,符合具體使用場(chǎng)景的解決方案才是好方案。

          最后

          歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ?
          回復(fù)「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會(huì)很認(rèn)真的解答喲!
          回復(fù)「交流」,吹吹水、聊聊技術(shù)、吐吐槽!
          回復(fù)「閱讀」,每日刷刷高質(zhì)量好文!
          如果這篇文章對(duì)你有幫助,在看」是最大的支持
          》》面試官也在看的算法資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持


          瀏覽 25
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色电影av网站 黄色黄色1级a片 黄色免费日本欧美 | 蜜臀久久精品久久久久消防站 | 日韩一级二级三级片 | 一区二区三区三级18岁看的 | 美女被操在线播放 |