SVG图标组件
本文档主要是在 Vue 项目中实现 svg-icon 组件,实现动态引入 svg,允许变更 svg 大小颜色的组件
# svg-sprite-loader
NPM:https://www.npmjs.com/package/svg-sprite-loader
这是一个神奇的依赖,它可以将引入的 svg 导入,然后可以直接就可以使用了
<svg><use xlink:href="#id"></use></svg>
1
# webpack 配置
注意在 vue-cli2.x 构建的项目中会默认有一条包含有 svg 格式的图片转成 base64 的 rules,要删除关于 svg 的配置
- vue-cli2.x
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: [resolve('src/icons/svg')],//文件目录
options: {
symbolId: 'icon-[name]' //名称前缀
}
},
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- vue-cli3.x
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
})
.end()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# svg-icon 组件
<template>
<div
v-if="isExternal(iconClass)"
:style="styleExternalIcon"
:class="externalClass"
v-on="$listeners"
/>
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true,
},
className: {
type: String,
},
size: {
// medium / small / mini
type: String,
default: 'medium',
},
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
return [
'svg-icon',
this.className ? 'svg-icon-' + this.className : '',
this.size ? 'svg-icon-' + this.size : '',
]
},
externalClass() {
return [
'svg-external-icon svg-icon',
this.size ? 'svg-icon-' + this.size : '',
]
},
isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`,
}
},
},
}
</script>
<style lang="scss">
.svg-external-icon {
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
}
.svg-icon,
.svg-icon-medium {
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
height: 22px;
width: 22px;
}
.svg-icon-small {
height: 18px;
width: 18px;
}
.svg-icon-mini {
height: 14px;
width: 14px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# 自动引入
可以使用自动化开发的require.context对于svg文件自动引入
const req = require.context('./svg', false, /\.svg$/)
const requireAll = (requireContext) => {
return requireContext.keys().map(requireContext)
}
requireAll(req)
1
2
3
4
5
6
2
3
4
5
6
上次更新: 2024/01/18, 10:44:15