# svgIcon 组件

# 背景

在某项目中,因有多个版本的 iconfont 字体图标库,导致项目难以维护。为了解决多版本私有图标库,使用 svgIcon 替换 iconfont 图标库。

# svg-spriter 介绍

# 工作原理

使用 svg-sprite-loader 实现自己的 Icon 组件,其实就是生成一张 svg 雪碧图。它的工作原理是: 利用 svg 的 symbol 元素,将每个 icon 包括在 symbol 中,通过 use 元素使用该 symbol。再通过<use xlink:href="#xxx"/>来显示你所需的 icon。

# 优点

  1. 每个 SVG 图标都可以更改大小颜色
  2. 页面代码清爽

使用的时候<svgIcon icon-class="sysHome" />

不需要加一个图标写一个样式 i.sysHome{background: url(../../assets/icon/sysHome.svg) no-repeat;}

  1. 解决各种版本 iconfont 私有图标库

# 开发流程

  1. 安装svg-sprite-loader
yarn add svg-sprite-loader -D
  1. 把 svg 图标存放在src/assets/icon目录下

新建index.js,加载所有的 svg,内容如下

const loadSvg = context => context.keys().map(context)
loadSvg(require.context('./', false, /\.svg$/))
  1. 配置vue.config.js
module.exports = {
  chainWebpack: config => {
    // set svg-sprite-loader
    config.module.rule('svg').exclude.add(resolve('src/assets/icon')).end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/assets/icon'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()
  }
}
  1. main.js中引入 svg 图标
import '@/assets/icon'
  1. 新建svgIcon组件,并全局注册
<template>
  <svg :class="svgClass" aria-hidden="true" v-on="$listeners">
    <use :xlink:href="iconName" />
  </svg>
</template>
<script>
export default {
  name: 'SvgIcon',
  props: {
    iconClass: {
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ''
    }
  },
  computed: {
    iconName() {
      return `#icon-${this.iconClass}`
    },
    svgClass() {
      if (this.className) {
        return 'svg-icon ' + this.className
      } else {
        return 'svg-icon'
      }
    }
  }
}
</script>

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

# svg 优化工具

svgo (opens new window) 是 svg 优化工具,可用来处理元数据、注释、隐藏元素、默认或非正规数值,以及其他不影响正常显示的东西。

# 拓展

React 项目中使用 svg 组件 (opens new window)