svg 图标

285 阅读1分钟

项目中的所有图标应该 统一 框架自带图标 阿里矢量图标 普通svg图标 通过 Symbol 的方式导入 多色图标与去色图标 需要将其分离 样式通用

.icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}

阿里矢量图标

分为两个js图标文件将去色与多色图标导入至main.js 去色图标才能更改颜色,可以将多色图标转为其它项目,然后批量去色

<svg class="icon" aria-hidden="true">
  <use xlink:href="#图标名字"></use>
</svg>

svg 图片图标

将图片分为两个文件夹中,文件一样,文件夹不同

在webpack中配置 相关参数

svg-sprite-loader 将svg转为Symbol 并需要忽略原本处理的url-loader

svgo-loader 将指定的文件夹中的svg去色

chainWebpack: config => {
    // set svg-sprite-loader
    // 忽略的文件
    config.module
      .rule('svg')
      .exclude.add(resolve('src/renderer/assets/icons'))
      .end()
    // 配置文件
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/renderer/assets/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      // folder 文件夹名字 name文件名
      .options({
        symbolId: 'icon-[folder]-[name]'
      })
      .end()
    // 去色文件夹
    config.module
      .rule('icon')
      .test(/\.svg$/)
      .include.add(resolve('src/renderer/assets/icons/svg_clear'))
      .end()
      .use('svgo-loader')
      .loader('svgo-loader')
      .tap(options => ({
        ...options,
        plugins: [{ removeAttrs: { attrs: 'fill' } }]
      }))
      .end()
 }

在一个js文件中 用require.context将所有的svg图片统一导入 并在main.js中导入这个js文件

const req_clear = require.context('./svg_clear', false, /\.svg$/)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
requireAll(req_clear)

然后 svg的图标用法和 阿里的矢量图标一样 注意去色图标

框架自带图标直接使用 i标签加类名即可


注意将其注册为全局组件,下面为封装的代码,有其它的处理,用自己的就好

<template>
  <el-tooltip
    class="item"
    effect="light"
    :content="tipText"
    placement="top"
    :disabled="!tipText"
    transition="el-zoom-in-bottom"
  >
    <div
      @click="clickBack"
      style="display: inline-block"
      :class="{ circle: isNormal }"
      v-waves="isNormal"
    >
      <div v-if="type === 'al' || type === 'img'">
        <svg
          :class="{ [iconClass]: iconClass }"
          :style="iconStyle"
          class="icon"
          aria-hidden="true"
        >
          <use :xlink:href="`${prefixName}${iconName}`"></use>
        </svg>
      </div>
      <div v-else-if="type === 'ele'">
        <i
          :style="iconStyle"
          :class="{ [iconName]: iconName, [iconClass]: iconClass }"
        ></i>
      </div>
    </div>
  </el-tooltip>
</template>

<script>
import waves from '@/directives/waves/index.js'
export default {
  directives: { waves },
  props: {
    // 图标库 al 阿里矢量图标库  ele 饿了么自带图标库  img svg图片
    type: {
      type: String,
      default: 'al'
    },
    // 是否更改颜色
    isSetColor: Boolean,
    iconName: String,
    iconStyle: String,
    iconClass: String,
    isNormal: Boolean,
    tipText: String
  },
  computed: {
    prefixName () {
      let prefixName = ''
      switch (this.type) {
        case 'al':
          prefixName = '#custom-icon-'
          break
        case 'img':
          prefixName = '#icon-svg-'
          break
      }
      if (this.isSetColor) {
        switch (this.type) {
          case 'al':
            prefixName = '#icon-'
            break
          case 'img':
            prefixName = '#icon-svg_clear-'
            break
        }
      }
      return prefixName
    }
  },
  methods: {
    clickBack () {
      this.$emit('clickBack')
    }
  }
}
</script>

<style lang="scss" scoped>
.icon {
  width: 1em;
  height: 1em;
  fill: currentColor;
  vertical-align: -0.15em;
  overflow: hidden;
}
.circle {
  border-radius: 50%;
  cursor: pointer;
}
</style>