VueでSVGアイコンコンポーネントを作成する方法



アイコンフォントからインラインSVGにベクトルアイコンを移行させる理由を考慮した後、アイコンフォントをSVGに置き換えるソリューションをVue.jsで見つけました。アイコンフォントを使う柔軟性と使い勝手を維持できます。CSSを使ってアイコンの大きさ、色、その他の属性を簡単に変えることができます。
一つの流行の方法は、v-htmlコマンドとnpmモジュールhttml-loaderを使用してSVGを私たちのVueテンプレートに導入し、Vueのライフサイクル関数mounted()にレンダリングされた<svg>要素を修正することです。CSSスタイルは、<svg>要素またはその親要素に直接適用でき、これらは多重化可能なコンポーネントを構成することができる。
Svg-inconコンポーネントを作成します。
Svg-incon.vueコンポーネントファイルを作成し、その中で三つのprop変数を受信します。
  • iconは、文字列タイプのprop変数を転送するために使用します。svgファイル名の導入
  • hasFillは、ブールタイプのprop変数であり、コンポーネントfill属性が<svg>要素の色を変更するために使用されるかどうかを教えます。デフォルト値はfalseであり、すなわちfill属性を使用しない
  • です。
  • growByHeightはブールタイプのprop変数であり、heightまたはwidthがfont-sizeに対してスケーリングされているかどうかを決定し、デフォルト値はtrueであり、すなわちheight
  • を使用する。
    
    <script>
    function recursivelyRemoveFill(el) {
     if (!el) {
      return;
     }
     el.removeAttribute('fill');
     [].forEach.call(el.children, child => {
      recursivelyRemoveFill(child);
     });
    }
    export default {
     name: 'svg-icon',
     props: {
      icon: {
       type: String,
       default: null
      },
      hasFill: {
       type: Boolean,
       default: false
      },
      growByHeight: {
       type: Boolean,
       default: true
      },
     },
     mounted() {
      if (this.$el.firstElementChild.nodeName === 'svg') {
       const svgElement = this.$el.firstElementChild;
       const widthToHeight = (svgElement.clientWidth / svgElement.clientHeight).toFixed(2);
       if (this.hasFill) {
        // recursively remove all fill attribute of element and its nested children
        recursivelyRemoveFill(svgElement);
       }
       // set width and height relative to font size
       // if growByHeight is true, height set to 1em else width set to 1em and remaining is calculated based on widthToHeight ratio
       if (this.growByHeight) {
        svgElement.setAttribute('height', '1em');
        svgElement.setAttribute('width', `${widthToHeight}em`);
       } else {
        svgElement.setAttribute('width', '1em');
        svgElement.setAttribute('height', `${1 / widthToHeight}em`);
       }
       svgElement.classList.add('svg-class');
      }
     }
    }
    </script>
    
    <template>
     <div v-html="require(`html-loader!../assets/svg/${icon}.svg`)" class="svg-container"></div>
    </template>
    
    <style lang="scss" scoped>
    .svg-container {
     display: inline-flex;
    }
    .svg-class {
     vertical-align: middle;
    }
    </style>
    svgアイコンファイルをrequire()を介してhttml-loader方法に渡します。この方法はファイルを文字列化してv-htmlコマンドでsvg元素にレンダリングします。
    すべての対<svg>元素の修正のところはmounted()ライフサイクルの方法の中にあります。
  • は、growByHeightによって定義される<svg>要素のheightまたはwidth属性を1 mに設定し、他の要素に対してwidthToHeightを使用する。すべてのSVGは正方形ではないので、レンダリングされた要素からwithToHeight比率を計算して、SVGは親要素のfont-size属性の大きさが変わる時に比例して元のサイズにスケールします。
  • は、<svg>要素のfill属性を設定するために、SVGファイル内部に付属するfill属性をカバーする必要がある。has Fill値がtrueであるとき、私たちは<svg>要素とそのサブ要素からFIll属性を再帰的に削除します。CSSセレクタを使用して、その親要素または要素にfill値を追加すればいいです。
  • はまた、構成要素内の範囲パターン
  • を設定するために、例えば、クラスなどの他のDOM属性を要素に追加することができる。
    スマイルアイコンを作成
    Font Awesomeと私たちのSvg-inconコンポーネントのアイコンフォントを使ってスマイルアイコンを作成します。

    アイコンフォントを使う
    
    <template>
     <i class="fas fa-smile smile-icon"></i>
    </template>
    
    <style lang="scss" scoped>
    .smile-icon {
     font-size: 24px;
     color: #aaa;
    
     &:hover {
     color: #666;
     }
    }
    </style>
    .smile-incon類のCSSセレクタ及びダミーセレクタ:hoverはアイコンのfont-sizeとカラー属性を設定します。
    Svg-inconコンポーネントを使用します。
    
    <script>
    import SvgIcon from './components/Svg-icon';
    
    export default {
     name: 'my-component',
     components: {
     'svg-icon': SvgIcon,
     },
    }
    </script>
    
    <template>
     <div class="smile-icon">
     <svg-icon icon="smile-solid" :hasFill="true"></svg-icon>
     </div>
    </template>
    
    <style lang="scss" scoped>
    .smile-icon {
     font-size: 24px;
     fill: #aaa;
    
     &:hover {
     fill: #666;
     }
    }
    </style>
    上の実装はアイコンフォントと同じで、smile-incon類は親要素の中で、Svg-inconコンポーネントの中で、色属性はfillに置き換えられます。私たちはまた、smile-solid.svgファイルがSvg-inconコンポーネントのrequire()メソッドによって指定された経路(./assites/svg/)にあることを確認しなければなりません。
    HTMLに描画
    これはv-htmlの出力によってレンダリングされたHTMLです。注意:すべてのfill属性を削除し、heightとwidth属性をに追加します。
    
    <div class="smile-icon">
     <svg height="1em" width="1em" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="smile" class="svg-inline--fa fa-smile fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
     <path d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm80 168c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm-160 0c17.7 0 32 14.3 32 32s-14.3 32-32 32-32-14.3-32-32 14.3-32 32-32zm194.8 170.2C334.3 380.4 292.5 400 248 400s-86.3-19.6-114.8-53.8c-13.6-16.3 11-36.7 24.6-20.5 22.4 26.9 55.2 42.2 90.2 42.2s67.8-15.4 90.2-42.2c13.4-16.2 38.1 4.2 24.6 20.5z">
     </path>
     </svg>
    </div>
    SVGに移行

    SVGは将来の発展方向と考えられているので、アイコンフォントの使いやすさを残した上で、アイコンフォントの使用を徐々に放棄したほうがいいです。Svg-inconコンポーネントは一例です。どのように利用可能なライブラリを使って要素の混乱部分を抜き出すかを教えてくれます。アイコンフォントを使うメリットを真似してください。
    締め括りをつける
    ここで、VueでSVGアイコンコンポーネントを作成する記事について紹介します。これに関連して、より多くのVue SVGアイコンコンポーネントの内容を紹介します。以前の文章を検索したり、下記の関連記事を引き続き閲覧したりしてください。これからもよろしくお願いします。