一、需求
由于Ant Design Vue提供的 Icon 图标满足不了项目的需求(需求图标未提供),所以我们使用了自定义的 SVG 图标
二、技术栈
- 前端框架:vue2 + Vue Cli
- 前端UI框架:Ant Design of Vue(v1.7.8)
三、方法一
- vue-svg-loader
- 这是Ant Design Vue官网的用法
安装依赖
npm i -D vue-svg-loader vue-template-compiler
# 或
yarn add --dev vue-svg-loader vue-template-compiler
本人使用的依赖版本:
vue-svg-loader@0.16.0
vue-template-compiler@2.6.14
配置vue.config.js
// vue.config.js
module.exports = {
chainWebpack: config => {
const svgRule = config.module.rule('svg');
svgRule.uses.clear();
svgRule.use('vue-svg-loader').loader('vue-svg-loader');
},
};
图标使用
<template>
<div>
<a-icon :component="bxAnaalyse" />
</div>
</template>
<script>
// 引入svg代码文件
import bxAnaalyse from '@/assets/icons/bx-analyse.svg';
export default {
data() {
return {
bxAnaalyse,
};
},
}
</script>
<style></style>
四、方法二
- vue-svg-icon-loader
- vue-svg-component-runtime
安装依赖
npm install --save-dev vue-svg-icon-loader
npm install vue-svg-component-runtime
本人使用的依赖版本:
vue-svg-component-runtime@1.0.1
vue-svg-icon-loader@2.1.1
配置vue.config.js
module.exports = {
chainWebpack: config => {
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
svgRule
.oneOf('inline')
.resourceQuery(/inline/)
.use('vue-svg-icon-loader')
.loader('vue-svg-icon-loader')
.end()
.end()
.oneOf('external')
.use('file-loader')
.loader('file-loader')
.options({
name: 'assets/[name].[hash:8].[ext]'
})
},
}
svg图标定义
在 assets
目录下新建 icons
文件夹,用于存放 svg
文件
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1551058675966" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7872" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M85.333333 512h85.333334a340.736 340.736 0 0 1 99.712-241.621333 337.493333 337.493333 0 0 1 108.458666-72.96 346.453333 346.453333 0 0 1 261.546667-1.749334A106.154667 106.154667 0 0 0 746.666667 298.666667C805.802667 298.666667 853.333333 251.136 853.333333 192S805.802667 85.333333 746.666667 85.333333c-29.397333 0-55.978667 11.776-75.221334 30.933334-103.722667-41.514667-222.848-40.874667-325.76 2.517333a423.594667 423.594667 0 0 0-135.68 91.264 423.253333 423.253333 0 0 0-91.306666 135.637333A426.88 426.88 0 0 0 85.333333 512z m741.248 133.205333c-17.109333 40.618667-41.685333 77.141333-72.96 108.416s-67.797333 55.850667-108.458666 72.96a346.453333 346.453333 0 0 1-261.546667 1.749334A106.154667 106.154667 0 0 0 277.333333 725.333333C218.197333 725.333333 170.666667 772.864 170.666667 832S218.197333 938.666667 277.333333 938.666667c29.397333 0 55.978667-11.776 75.221334-30.933334A425.173333 425.173333 0 0 0 512 938.666667a425.941333 425.941333 0 0 0 393.258667-260.352A426.325333 426.325333 0 0 0 938.666667 512h-85.333334a341.034667 341.034667 0 0 1-26.752 133.205333z" p-id="7873"></path><path d="M512 318.378667c-106.752 0-193.621333 86.869333-193.621333 193.621333S405.248 705.621333 512 705.621333s193.621333-86.869333 193.621333-193.621333S618.752 318.378667 512 318.378667z m0 301.909333c-59.690667 0-108.288-48.597333-108.288-108.288S452.309333 403.712 512 403.712s108.288 48.597333 108.288 108.288-48.597333 108.288-108.288 108.288z" p-id="7874"></path></svg>
统一加载
新建 icons.js
,统一加载所有自定义图标,方便管理
// icons.js
/**
* 自定义图标加载表
* 所有图标均从这里加载,方便管理
*/
// https://www.webpackjs.com/configuration/module#ruleresourcequery
// ?inline 与webpack的resourceQuery 有关,删除会报错
import bxAnaalyse from '@/assets/icons/bx-analyse.svg?inline' // path to your '*.svg?inline' file.
export { bxAnaalyse }
Rule.resourceQuery
Rule.resourceQuery
是webpack
中的一个配置项,用于指定模块的资源类型。- 它的作用是在
webpack
编译时,根据指定的资源类型,将符合条件的模块进行处理。 - 比如,我们可以使用
Rule.resourceQuery
来指定处理以特定后缀名结尾的文件,或者处理特定类型的文件。 - 这样,可以在
webpack
编译时只对需要处理的模块进行处理,提高编译效率
// 如果不想使用Rule.resourceQuery, 将代码做如下修改即可
import bxAnaalyse from '@/assets/icons/bx-analyse.svg'
export { bxAnaalyse }
// vue.config.js中删除.resourceQuery(/inline/)
module.exports = {
chainWebpack: config => {
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
svgRule
.oneOf('inline')
.use('vue-svg-icon-loader')
.loader('vue-svg-icon-loader')
.end()
.end()
.oneOf('external')
.use('file-loader')
.loader('file-loader')
.options({
name: 'assets/[name].[hash:8].[ext]'
})
},
}
图标使用
用法一
<template>
<div>
<a-icon :component="bxAnaalyse" />
<a-button type="primary" >
<a-icon :component="bxAnaalyse" />我是按钮
</a-button>
</div>
</template>
<script>
import { bxAnaalyse } from '@/core/icons.js'
export default {
data() {
return {
bxAnaalyse,
};
},
}
</script>
<style></style>
用法二
<template>
<div>
<bxAnaalyse class="icon"></bxAnaalyse>
</div>
</template>
<script>
import { bxAnaalyse } from '@/core/icons.js'
export default {
components: {
bxAnaalyse,
},
}
</script>
<style>
.icon {
width: 1em;
height: 1em;
}
</style>
区别
用法一单位是 em
,用法二是 Number
,所以如果要用法一和用法二显示效果一致,需要手动给用法二设置宽高为 1em
遇到的问题
解决方案
- 检查
svg
图标的引入路径是否正确 - 检查
vue.config.js
配置是否正确 - 检查是否在
vue.config.js
中配置了.resourceQuery(/inline/)
,但是import
路径中没有添加?inline
目录结构
五、方法三
-
svg-sprite-loader
-
参考文章