# 让项目支持SVG

# 创建icon-component组件

// components/SvgIcon
<template>
  <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
  <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
    <use :href="iconName" />
  </svg>
</template>

<script>
import { isExternal } from '@/utils/validate'

export default {
  name: 'SvgIcon',
  props: {
    iconClass: {
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ''
    }
  },
  computed: {
    isExternal () {
      return isExternal(this.iconClass)
    },
    iconName () {
      return `#icon-${this.iconClass}`
    },
    svgClass () {
      if (this.className) {
        return 'svg-icon ' + this.className
      } else {
        return 'svg-icon'
      }
    },
    styleExternalIcon () {
      return {
        mask: `url(${this.iconClass}) no-repeat 50% 50%`,
        '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
      }
    }
  }
}
</script>

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

.svg-external-icon {
  background-color: currentColor;
  mask-size: cover!important;
  display: inline-block;
}
</style>

# 使用svg-sprite-loader处理SVG

接下来我们在vue-cli基础上进行改造,配置svg-sprite-loader,将多个SVG打包成svg-sprite。 我们不能保证所有的SVG都是用来作为Icon的,并且url-loader会将所有SVG处理成base64,所以使用webpack 的excludeinclude,让url-loader处理除此文件夹之外的SVG,svg-sprite-loader只处理指定文件夹下的SVG。Electron-vue也可参照。

{
  test: /\.svg$/,
  include: [resolve('src/icons')],
  use: {
    loader: 'svg-sprite-loader',
    options: {
      symbolId: 'icon-[name]'
    }
  }
},
{
  test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  exclude: [resolve('src/renderer/icons')],
  use: {
    loader: 'url-loader',
    query: {
      limit: 10000,
      name: 'imgs/[name]--[folder].[ext]'
    }
  }
}

# Nuxt.js支持,修改nuxt.config文件

build: {
  extend (config, ctx) {
    const svgRule = config.module.rules.find(rule => rule.test.test('.svg'))
    svgRule.exclude = [path.resolve(__dirname, 'assets/svg')]
    // Includes /icons/svg for svg-sprite-loader
    config.module.rules.push({
      test: /\.svg$/,
      include: [path.resolve(__dirname, 'assets/svg')],
      loader: 'svg-sprite-loader',
      options: {
        symbolId: 'icon-[name]',
      },
    })
  }
}

# 自动导入

创建一个专门存放SVG图标的文件夹@src/icons,将所有SVG图标放到该文件夹下。之后使用webpack的require.context (opens new window),通过正则引入SVG图标文件

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

# 页面使用

<svg-icon class="login" />

文章参考:手摸手,带你优雅的使用 icon (opens new window)

上次更新时间: 11/7/2021, 2:23:15 PM

添加微信

获取阿里云更多优惠

阿里云最新活动