封裝svg組件

Author: 微笑向暖_Tinicss

原文連接:juejin.im/post/5cf79b…html

如何封裝svg圖標組件

封裝svg圖標組件的方法有不少種,若是隻是單純的想使用svg圖標,能夠將svg導出fonts字體圖標使用,但這樣作會失去svg原有的樣式與尺寸,也能夠當成img圖片或者背景引入,但這樣作很是繁瑣。vue

最近項目中須要用大量的svg圖標,這裏介紹一種經過vue組件使用svg圖標的方式:webpack

首先了解一下svg圖標的use元素。git

<svg>
  <defs>
    <g id="shape">
        <rect x="0" y="0" width="50" height="50" />
        <circle cx="0" cy="0" r="50" />
    </g>
  </defs>

  <use xlink:href="#shape" x="50" y="50" />
  <use xlink:href="#shape" x="200" y="50" />
</svg>
複製代碼

好比我繪製了一個id爲shape的svg元素,當我想複用時,不可能再複製粘貼一遍代碼,這時藉助use元素,讓xlink:href指定爲#shape,它會去尋找並克隆對應的svg元素,從而實現複用。github

use元素方便的是,只要同處於一個文檔中,use均可以引用到,它能夠重用單個元素,也能夠重用一組<g>或者<symbol>元素,只須要經過id選擇器進行標時引用便可。web

具體的想要了解use克隆的內容放在了哪裏,以及svg更底層的內容,可參考:用CSS給SVG 的內容添加樣式vue-cli

封裝vue組件

首先,將UI提供的須要使用的svg文件統一放在一個文件夾內:bash

├── src
    ├── svg
        ├── user.svg
        └── course.svg
複製代碼

開發vue組件:svg

// svg-icon.vue
<template>
  <svg :class="svgClass" aria-hidden="true" v-on="$listeners">
    <use :xlink:href="iconName"></use>
  </svg>
</template>

<script>
import './icons';

export default {
  name: 'SvgIcon',
  props: {
    // svg圖標名稱
    name: {
      default: ''
    },
    // 自定義樣式
    className: {
      type: String,
      default: ''
    }
  },
  computed: {
    iconName() {
      return `#icon-${this.name}`;
    },
    svgClass() {
      return [
        'svg-icon',
        this.className ? this.className:''
      ]
    }
  }
};
</script>

<style scoped>
.svg-icon {
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>
複製代碼

咱們指望使用svg-icon組件來統一使用全部的svg文件,經過指定name來變動對應的svg文件。

想要使用svg文件的話,還須要將全部svg文件統一加載到內存當中,可使用import 'svg/user.svg'這種方式一個一個引用,這裏藉助require.context一次性引入全部svg文件。

// icons.js

const req = require.context('@svg', false, /\.svg$/);
const requireAll = requireContext => requireContext.keys().map(requireContext);
requireAll(req);
複製代碼

這個時候,還不能經過svg-icon組件指定name的方式來引用兌用svg文件。咱們還須要將每一個svg文件進一步處理,將他們文件內容的icon封裝進symbol元素中,達到下面的使用效果:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <symbol class="icon" viewBox="0 0 970 740" id="icon-user">...</symbol>
</svg>
複製代碼

這裏能夠藉助webpack插件:svg-sprite-loader

改造項目的webpack配置

因爲項目是基於vue-cli3定製的,因此這裏只介紹一下如何在vue-cli3中配置svg-sprite-loader

代碼以下:

module.exports = {
    ...
    chainWebpack: config => {
        ...
        config.module
          .rule('svg')
          .exclude.add(resolve('src/svg'))
          .end();
        config.module
          .rule('svgs-loader')
          .test(/\.svg$/)
          .include.add(resolve('src/svg'))
          .end()
          .use('svg-sprite-loader')
          .loader('svg-sprite-loader')
          .options({
            symbolId: 'icon-[name]'
          })
          .end();
    }
}
複製代碼

這裏要注意一下,配置svg-sprite-loader以前,要先替換vue-cli3自己的file-loader規則,該loader會把svg同圖片資源同樣單獨輸出出來,這裏配置file-loader忽略svg下面全部的svg文件便可。

最後,在vue中就能夠經過svg-icon組件來使用對應的svg圖標了。

相關文章

如文章內容出現錯誤,敬請諒解,但願能夠不吝賜教。

轉載請註明出處

相關文章
相關標籤/搜索