在Vue项目中使用svgIcon图标

474 阅读1分钟

在页面中以 symbol 引用的方式使用 SVG,已经成为目前最完美的图标解决方案。使用 SVG Symbol,把一个个图标合并成一个包含多个 symbol 的 SVG 文件。在需要使用图标的地方,引用对应的 symbol 即可。

svg-sprite-loader 安装和配置

  1. 安装
# npm
npm install svg-sprite-loader -D
# yarn
yarn add svg-sprite-loader -D
  1. 配置
  • 打开vue.config.js文件,在chainWebpack函数中新增配置
  • svg文件放在src/assets/img/icon-svg目录下
module.exports = {
    chainWebpack: (config) => {
    config.module
      .rule('svg')
      .exclude.add(resolve('src/assets/img/icon-svg'))
      .end();
    config.module
      .rule('svg-sprite-loader')
      .test(/\.svg$/)
      .include.add(resolve('src/assets/img/icon-svg'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end();
  }
}

使用 svg-sprite-loader的坑

  • svg可能已经设置了fill属性,如果有此属性,那么引入的svg无法通过css更改颜色。因此在引入前应将fill属性删除
  • svgo-loader : 自动去除fill属性

安装

# npm
npm install svgo-loader --dev
# yarn
yarn add svgo-loader --dev

配置

module.exports = {
    chainWebpack: (config) => {
    config.module
      .rule('svg-sprite-loader')
      .test(/\.svg$/)
      .include.add(resolve('src/assets/img/icon-svg'))
      .end()
      .use('svg-sprite-loader').loader('svg-sprite-loader').options({symbolId: 'icon-[name]'}).end()
      .use('svgo-loader').loader('svgo-loader') .tap(options => ({...options, plugins: [{removeAttrs: {attrs: 'fill'}}]})).end()
  }
}

封装SvgIcon组件

<template>
  <svg class="svg-icon" aria-hidden="true">
    <use :xlink:href="iconName"></use>
  </svg>
</template>

<script>
export default {
  name: 'SvgIcon',
  props: {
    name: {
      type: String,
      default: ''
    }
  },
  computed: {
    IconName () {
      return `#icon-${this.name}`;
    }
  }
};
</script>

<style scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

创建一个index.js文件

  • src/assets/img目录下新增index.js文件
import Vue from 'vue';
import SvgIcon from '@/components/SvgIcon';
// 全局注册svgIcon组件
Vue.component(SvgIcon.name, SvgIcon);

// 使用require.context自动导入文件
const requireAll = requireContext => requireContext.keys().map(requireContext);
const req = require.context('../img', true, /.svg$/);
requireAll(req);

在main.js中引入

import '@/assets/img/index';

组件使用

<svg-icon name="iconName"></svg-icon>