Vite2 + Vue3添加svg的使用并通过svg实现自定义Icon组件

1、安装依赖插件vite-plugin-svg-icons

1
yarn add vite-plugin-svg-icons -D 

1
npm i vite-plugin-svg-icons -D

2、安装glob

不安装会提示Error: Cannot find module 'fast-glob'

1
yarn add fast-glob -D

1
npm install fast-glob -D

3、配置vite.config.ts

3.1 iconDirs所有的 svg的文件都存放在该文件夹下

3.2 symbolId指定use标签中href格式

导出名为createSvgIconsPlugin并加大括号,不然会提示TypeError: (0 , import_vite_plugin_svg_icons.default) is not a function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { defineConfig } from 'vite'
import { resolve } from 'path'
import {createSvgIconsPlugin} from 'vite-plugin-svg-icons';

export default defineConfig({
plugins: [
createSvgIconsPlugin({
// 指定要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/svg')],
// 执行icon name的格式
symbolId: 'icon-[name]',
})
]
});

3、在main.ts注册脚本

1
import 'virtual:svg-icons-register'; // 引入svg icon注册脚本

4、通过svg实现Icon组件

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
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName" :fill="color" />
</svg>
</template>

<script>
import { computed, defineComponent } from 'vue'
export default defineComponent({
props: {
name: {
type: String,
default: ''
},
color: {
type: String,
default: ''
},
},
setup(props) {
return {
iconName: computed(() => `#icon-${props.name}`),
svgClass: computed(() => {
if (props.name) {
return `gulu-icon ${props.name}`
}
return 'gulu-icon'
})
}
}
})
</script>

<style lang="scss" scoped>
.gulu-icon {
width: 3em;
height: 3em;
position: relative;
fill: currentColor;
vertical-align: -2px;
}
</style>

5、引用自定义Icon组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<Icon name = "alipay" />
<Icon name = "qq" />
<Icon name = "wechat" />
</template>

<script lang="ts">
import {
Icon,
} from './lib/index'

export default {
components: {
Icon
}
}
</script>