Vue中引入SVG格式图片

506 阅读2分钟

前言:在学习过程中遇到vue中如何引入svg格式图片的问题,本人感觉配置比较繁琐,而且也遇到了一些问题,故将其记录下来,方便后面自己使用,如果其他伙伴有更好的办法,也希望不吝赐教

一、安装svg-sprite-loader

1.使用命令行

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

2.使用UI界面

在运行依赖中查找'svg-sprite-loader',然后进行安装

二、配置svg-sprite-loader

1.因为学习过程中使用的TypeScript,所以首先在'shims-vue.d.ts'中,添加如下配置

declare module "*.svg" {
  const content: string;
  export default content;
}

2.在'vue.config.js'中进行如下配置

const path = require("path");
module.exports = {
  lintOnSave: false,
  chainWebpack: (config) => {
    const dir = path.resolve(__dirname, "src/assets/icon"); // 这里的路径需要根据自己的实际路径进行修改
    config.module
      .rule("svg-sprite")
      .test(/\.svg$/)
      .include.add(dir)
      .end()
      .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);
  },
};

    这里注意我遇到了一个问题:上述代码需要require的地方会报错:'Require statement not part of import statement.' 其实这是一个eslint报警,解决方法有很多。
    我采用的是在报警代码上方添加代码:'// eslint-disable-next-line @typescript-eslint/no-var-requires'

三、在html中引入对应svg图片

<template>
   <svg>
        <use xlink:href="#money" /> //#后面填写svg图片的名称
   </svg>
</template>
<script>
  import  "@/assets/icon/money.svg"; // 将你下载好的svg文件导入
</script>

    到这里,我们引入svg图片的过程就基本完成了,但是由于我们变动了配置文件'vue.config.js',所以我们需要重启热更新服务器之后,我们的配置才能生效。这点也是新手比较容易犯错的地方,我当时就是因为没有重启服务器,导致配置无法生效,希望大家引以为戒。

四、抽离Icon组件

    通过上面的步骤,我们已经可以将svg图片引入,但是这样做有个缺点。我们每引入一个svg图片,我们都需要将第三步骤的代码重复一次。这样很不利于后续的使用,根据组件化的思想,我们把svg图片抽离成一个组件,方便我们的开发。

<template>
  <svg class="icon" aria-hidden="true">
    <use :xlink:href="'#' + name" /> // name这里填写svg的名称,不需要加'.svg'后缀
  </svg>
</template>
<script lang="ts">
import Vue from "vue";
// 批量导入svg文件,不需要单独import文件
const importAll = (requireContext: __WebpackModuleApi.RequireContext) =>
  requireContext.keys().forEach(requireContext);
try {
  importAll(require.context("../assets/icon", true, /\.svg$/)); // 这里面的路径要根据自己的实际路径进行修改
} catch (e) {
  console.log(e);
}

export default Vue.extend({
// 给我们抽离的组件添加'name'属性,便于调用不同的图片
  props: ["name"],
});
</script>
<style lang="scss" scoped>
// 图片样式,这样可以根据自己需求修改
.icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

五、fill属性去除

    svg图片可能自身携带'fill'属性,会对我们添加自己的CSS样式产生干扰,这里提供两种方法删除此属性。
    1.一个简单但操作量较大的方法是直接将生成的svg文件中的'fill'属性手动删除
    2.通过引入'svgo-loader'依赖,自动将'fill'属性删除。下面是此依赖'vue.config.js'的配置方法:

config.module
            .use('svgo-loader').loader('svgo-loader')
            .tap(options=>({...options,plugins:[{removeAttrs:{attrs:'fill'}}]})).end();

    这里可能遇到的问题点:我们引入'svgo-loader'依赖的同时,要保证'svgo'依赖存在,如果没有,系统会报错,所以建议安装的时候将'svgo'一起安装