Vue2 使用 SVG (在使用TS环境下)

286 阅读1分钟

1、下载想要使用的 SVG

将 svg 文件放到你的 Vue 项目中

2、import 引入

 import x from '@/assets/icons/bill.svg'

这时会有如下的报错

222.png 如何解决

在 shims-vue.d.ts 文件中加入如下代码即可解决

declare module '*.svg' {
  const content: any;
  export default content;
}

3、安装 SVG sprite loader

npm install svg-sprite-loader -D
# via yarn
yarn add svg-sprite-loader -D

4、在 vue-config.js 文件中添加配置

const path = require('path')

module.exports = {
    lintOnSave: false,
    chainWebpack: config => {
        const dir = path.resolve(__dirname, 'src/assets/icons') // 确定 icons 的目录

        config.module
            .rule('svg-sprite') // 添加 svg-sprite 规则
            .test(/.svg$/) // 匹配上该正则的文件才能使用这个规则
            .include.add(dir).end() // 只包含 icons 目录 走这个规则
            .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract: false}).end()
        
        config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}])
        config.module.rule('svg').exclude.add(dir) // 其他 svg loader 排除 icons 目录

    }
}

5、使用

如果你已运行 yarn serve 服务,请重新开启 yarn serve

<svg>
    <use xlink:href="#bill" /> // # + 'id'
</svg>

你会发现每次使用都要引入 svg

6、如何直接引入所有 svg

在想要使用组件中 或者 全局 中写如下代码

<script lang="ts">
  let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
  try {
    importAll(require.context('../assets/icons', true, /.svg$/));
  } catch (error) {
    console.log(error);
  }
  export default {
    props: ['name'],
    name: 'Icon'
  };
</script>

7、封装 Icon.vue 组件

<template>
    <svg class="icon">
        <use :xlink:href="'#'+name"/>
    </svg>
</template>

<script lang="ts">
  let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
  try {
    importAll(require.context('../assets/icons', true, /.svg$/));
  } catch (error) {
    console.log(error);
  }
  export default {
    props: ['name'],
    name: 'Icon'
  };
</script>

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

8、快乐使用 Icon.vue 组件

<Icon name="xxx"/>

9、这样使用还存在 bug

svg 文件其实存放的是 xml 标签,其中可能会出现 fill=" " 的代码,如下图

Snipaste_2022-11-20_18-58-58.png

这样会导致我们在使用过程中,无法在 svg 文件外部对 svg 颜色的修改,只能在文件内将 fill=" " 该代码删除,如果引入较多的 svg 文件,将要一个一个删除,非常麻烦,可能还会漏删。所以找到一个解决方法

1、在 vue.config.js 文件中添加一个 loader ,可以自动删除 svg 文件中的 fill=" " 字段

const path = require('path')

module.exports = {
    lintOnSave: false,
    chainWebpack: config => {
        const dir = path.resolve(__dirname, 'src/assets/icons') // 确定 icons 的目录

        config.module
            .rule('svg-sprite') // 添加 svg-sprite 规则
            .test(/.svg$/) // 匹配上该正则的文件才能使用这个规则
            .include.add(dir).end() // 只包含 icons 目录 走这个规则
            .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract: false}).end()
          // 添加的 loader
            .use('svgo-loader').loader('svgo-loader')
            .tap(options => ({...options, plugins: [{removeAttrs: {attrs: 'fill'}}]})).end()
            
        config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}])
        config.module.rule('svg').exclude.add(dir) // 其他 svg loader 排除 icons 目录

    }
}

2、安装 svgo-loader

yarn add --dev svgo-loader

3、再重新开启 yarn serve

如果你配置svgo-loader后,发现icon显示不出来,请注释或删掉下面这行配置,然后手动删除svg文件里的fill属性即可

2021-11-6-20-42-14.png

10、vue.config.js 报 eslint 错误怎么办?

2020-8-6-17-40-56.png

/* eslint-disable */ 

把上面这句话添加到 vue.config.js 的第一行即可