《记账-svg引入icon》

815 阅读2分钟

目标:底部导航栏里的三个小图标

在阿里巴巴图标库里下载想要的图标,要选择svg下载。之后可以把下载好的svg文件放到assets/icons目录里(新建)。

在Nav.vue组件里引入这三个svg文件:

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

但是发现这样会有警告,说找不到这个模块。是因为typescript里引入svg需要做一些别的,搜索之后发现可以在以.d.ts 结尾的文件里添加:

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

就可以引入了。

svg-sprite-loader

还要使用这个loader。

安装

yarn add svg-sprite-loader -D

配置

官网上给出的配置是在webpack.config.js里的写法,但是我们通过vue @cli搭建的项目,并没有webpack的配置文件,所以只能在vue.config.js文件里配置

const path = require('path')

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

    config.module
        .rule('svg-sprite')
        .test(/\.svg$/)
        .include.add(dir).end() // 包含 icons 目录
        .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract:false}).end()
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}])
    config.module.rule('svg').exclude.add(dir) // 其他 svg loader 排除 icons 目录

  }
}

配置好以后,就可以使用导入的svg了。

<router-link to="/labels">
    <svg>
        <use xlink:href="#label"/>
    </svg>
    标签
</router-link>

在要展示图标的位置,写一个svg标签,里边use标签,使用xlink:href="#label"属性,# 加 svg的文件名

那么这个loader做了什么呢?

  1. 把import 的x 变成symbol标签
  2. 把symbol标签包在svg标签里
  3. 把svg标签放到body里

每个symbol标签里的id就是svg的文件名

把导入的东西打印出来看看:

import x from '@/assets/icons/label.svg'
import y from '@/assets/icons/money.svg'
import z from '@/assets/icons/statistics.svg'

console.log(x);
console.log(y);
console.log(z);

和body里的symbol标签里的东西一样。

改进1 :import一个目录

上边想引入svg需要一个一个import,能不能直接用几句代码代替所有的import?

//Nav.vue
<script lang="ts">
    const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
    try {importAll(require.context('../assets/icons', true, /\.svg$/));} catch (error) {console.log(error);}

</script>

添加这两行代码,就可以代替所有的import svg文件,直接import 所有icons所在的目录,效果是一样的。

自动删除fill属性

下载的icon图标有的自己有颜色,就导致之后无法改变图标的颜色。

我们粘贴到项目中的.svg图标里边的内容是xml,如图所示:

在path标签里如果存在fill属性,那么该图标就无法改变它的颜色了。如果删掉fill属性就可以。

但是如果有很多个.svg图标,一个一个检查就很麻烦。

svgo-loader

安装

yarn add --dev svgo-loader

配置

和svg-sprite-loader配置类似,还是在vue.config.js文件里,

config.module
        .rule('svg-sprite')
        .test(/\.svg$/)
        .include.add(dir).end() // 包含 icons 目录
        .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract:false}).end()
        .use('svgo-loader').loader('svgo-loader')   //add
        .tap(options => ({...options, plugins: [{removeAttrs: {attrs: 'fill'}}]})).end()   //add

添加后两行配置

这样做,就可以做到把引入的svg图标的fill删掉,之后就可以通过css修改颜色了。

有助于理解的博客