环境:

  • vue-cli 3.0
  • vue @2.x

安装插件 svg-sprite-loader

  1. $ npm i svg-sprite-loader -D

webpack配置

在根目录的vue.config.js里添加如下代码:

  1. module.exports = {
  2. chainWebpack(config) {
  3. // set svg-sprite-loader
  4. config.module
  5. .rule('svg')
  6. .exclude.add(resolve('src/icons'))
  7. .end();
  8. config.module
  9. .rule('icons')
  10. .test(/\.svg$/)
  11. .include.add(resolve('src/icons'))
  12. .end()
  13. .use('svg-sprite-loader')
  14. .loader('svg-sprite-loader')
  15. .options({ symbolId: 'icon-[name]' })
  16. .end();
  17. },
  18. };

在创建svgIcon组件

在src/components下创建组件SvgIcon/index.vue,组件内容如下:

  1. <template>
  2. <div
  3. :style="styleExternalIcon"
  4. class="svg-external-icon svg-icon"
  5. v-if="isExternal"
  6. v-on="$listeners"
  7. />
  8. <svg :class="svgClass" aria-hidden="true" v-else v-on="$listeners">
  9. <use :xlink:href="iconName" />
  10. </svg>
  11. </template>
  12. <script>
  13. import { isExternal } from '@/util/validate';
  14. export default {
  15. name: 'SvgIcon',
  16. props: {
  17. iconClass: {
  18. type: String,
  19. required: true,
  20. },
  21. className: {
  22. type: String,
  23. default: '',
  24. },
  25. },
  26. computed: {
  27. isExternal() {
  28. return isExternal(this.iconClass);
  29. },
  30. iconName() {
  31. return `#icon-${this.iconClass}`;
  32. },
  33. svgClass() {
  34. if (this.className) {
  35. return 'svg-icon ' + this.className;
  36. } else {
  37. return 'svg-icon';
  38. }
  39. },
  40. styleExternalIcon() {
  41. return {
  42. mask: `url(${this.iconClass}) no-repeat 50% 50%`,
  43. '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`,
  44. };
  45. },
  46. },
  47. };
  48. </script>
  49. <style scoped>
  50. .svg-icon {
  51. width: 1em;
  52. height: 1em;
  53. vertical-align: -0.15em;
  54. fill: currentColor;
  55. overflow: hidden;
  56. }
  57. .svg-external-icon {
  58. background-color: currentColor;
  59. mask-size: cover !important;
  60. display: inline-block;
  61. }
  62. </style>

这里还缺一个validate.js,创建文件src/util/validate.js

  1. export function isExternal(path) {
  2. return /^(https?:|mailto:|tel:)/.test(path);
  3. }

创建icons目录

在src下创建icons目录,目录结构如下:

  1. icons
  2. |_ svg
  3. |_ xxx.svg
  4. |_ index.js
  5. |_ svgo.yml

index.js的内容:

  1. import Vue from 'vue';
  2. import SvgIcon from '@/components/Common/SvgIcon/index.vue'; // svg component
  3. // register globally
  4. Vue.component('svg-icon', SvgIcon);
  5. const req = require.context('./svg', false, /\.svg$/);
  6. const requireAll = requireContext => requireContext.keys().map(requireContext);
  7. requireAll(req);

svgo.yml的内容:

  1. # replace default config
  2. # multipass: true
  3. # full: true
  4. plugins:
  5. # - name
  6. #
  7. # or:
  8. # - name: false
  9. # - name: true
  10. #
  11. # or:
  12. # - name:
  13. # param1: 1
  14. # param2: 2
  15. - removeAttrs:
  16. attrs:
  17. - 'fill'
  18. - 'fill-rule'

在main.js里导入icons

  1. import './icons'; // icon

使用svg-icon

  1. <svg-icon icon-class="count" class-name="my-icon" />
  • icon-class 是图标的文件名
  • class-name 是自定义的class名

注:修改了vue.config.js要重新运行项目才有效