Элегантное использование SVG в Vue.js

1. Установите и настройте

1.1 Установите svg-спрайт-загрузчик

npm i svg-sprite-loader

Установите svg-спрайт-загрузчик. Проекты, созданные с помощью скаффолдинга vue-cli, по умолчанию будут использовать url-loader для обработки SVG, поэтому его необходимо обработать.

1.2 Настройте зависимости и загрузчики svg в webpack.base.conf

Используйте include, include и img, чтобы различать. Затем измените конфигурацию webpack.base.conf.js, чтобы svg-sprite-loader обрабатывал только файлы в указанных нами src/icons.

//vue-cli 2.x
{
   test: /\.svg$/,
   loader: 'svg-sprite-loader',  //Configure the loader to process svg files
   include: [resolve('src/icons')],  //Specify the folder processed by the loader, and later we will put the svg file in the src/icon folder
   options: {
       symbolId: 'icon-[name]' //correspond<use:xlink:href="iconName"/>
   }
},
{
   test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
   loader: 'url-loader',
   exclude: [resolve('src/icons')],   //url-loader Do not process this folder
   options: {
     limit: 10000,
     name: utils.assetsPath('img/[name].[hash:7].[ext]')
   }
}  
//vue-cli 3.x
//Create a new vue.config.js file in the root directory
const path = require('path');
const { config } = require('process');
function resolve(dir) {
    return path.join(__dirname, dir)
}
module.exports = {
    //base path
    publicPath: './',  //The default '/' is an absolute path, if you are not sure about the root path, change it to a relative path './'
    // output file directory
    outputDir: 'dist',
    assetsDir: 'static',
    chainWebpack: (config) => {
         //Configure aliases
            config.resolve.alias
              .set('@', resolve('src'))
              .set('assets', resolve('src/assets'))
              .set('components', resolve('src/components'))
              .set('utils', resolve('src/utils'));
            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();
        },
};

1.3 созданный каталог файлов (создайте папку со значками в папке src)

2. Используйте

2.1 Зарегистрируйте интересный компонент

Создайте папку SvgIcon в компонентах и ​​создайте файл Svg.vue.

<template>
  <svg :class="svgClass" aria-hidden="true" v-on="$listeners">
    <use :xlink:href="iconName"/>
  </svg>
</template>
<script>
export default {
  name: 'SvgIcon',
  props: {
    //<svg-icon icon>
    iconClass: {  
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ''
    }
  },
  computed: {
    iconName() {
      return `#icon-${this.iconClass}`   //icon-class='.svg file name' ==> '#icon-.svg file name'
    },
    svgClass() {
      if (this.className) {
        return 'svg-icon ' + this.className  //className for the added style
      } else {
        return 'svg-icon'
      }
    }
  }
}
</script>
<style scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

2.2 Запись в index.js под иконками

Используйте require.context для автоматического импорта файлов без их импорта по одному.

import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon' // svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req)

2.3 Добавление значка в main.js

Добавьте файл index.js в main.js.

import '@/icons' // icon

2.4 Использование компонентов на страницах

Использовать иконку каждый раз очень удобно, нужно знать всего одну строчку кода

<svg-icon icon-class="user" />

Это все, спасибо.

Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn и Discord.