最近开发中使用到一个好玩的Vite
三方小插件vite-plugin-svg-icons
很实用,可以辅助我们开发过程中快速加载svg
小图标。其原理是在Vite
编译器的时候通过一次性的DOM
操作将SVG
插入DOM
结构中,然后通过使用内联SVG
进行加载访问,极大的方便了我们的小图标引用模式。 若只是少量的svg
图片加载建议食用,若是svg图片数量过多并不建议采用(过多的svg
文件插入也会导致我们的html
文件过大)。
安装
通过上述了解后,接下我们来配置使用vite-plugin-svg-icons
插件,该插件需要Vite
支持。
less
$ npm i vite-plugin-svg-icons -D // 或
$ yarn add vite-plugin-svg-icons -D // 或
$ pnpm i vite-plugin-svg-icons -D
由于其主要是在编译打包期生效,所以放在devDependencies
中即可。
配置
安装完成后,需要在vite.config.ts
中引入该插件,并配置对应svg
地址:
typescript
// vite.config.ts
import * as path from 'node:path'
import type { ConfigEnv, UserConfig } from 'vite'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import Unocss from 'unocss/vite'
export default ({ mode }: ConfigEnv): UserConfig => {
return {
plugins: [
vue(),
vueJsx(),
Unocss(),
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/bpmn-icons')],
// 指定symbolId格式
symbolId: '[name]',
customDomId: '__svg__icons__dom__',
}),
],
}
在vite.config.ts
配置完成后还需要再程序的入口处引入virtual:svg-icons-register
库用于注册插入SVG
的DOM
树:
arduino
// main.ts
import 'virtual:svg-icons-register'
.......
封装组件
完成上述的配置操作后,我们就可以封装一个内联SVG
方便随时使用了,我这里使用的VUE3
作为开发框架,你也可以使用React、nextjs
等进行封装,原理相同。
xml
// svg-icon.vue
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'BpmnIcon',
inheritAttrs: false,
props: {
name: {
type: String,
default: 'bpmn-icon-process',
},
color: {
type: String,
default: '#1d1d1f',
},
},
})
</script>
<template>
<svg class="bpmn-icon h-[40px] w-[40px]" aria-hidden="true">
<use :xlink:href="`#${name}`" :fill="color" />
</svg>
</template>
上述有用到unocss
方式进行样式渲染,配置使用请参考前文:【开发一个Vue3组件】 | 如何创建一个本地库项目
使用
通过上述封装操作后,我们就可以和其他组件一样来使用这个组件了,这里使用的是我一个已有项目的代码不额外写一个测试页面了,因为使用的确特别的简单,示例代码如下:
javascript
// test.vue
<div class="panel-header flex items-center gap-5 bg-light-300 px-3 py-5">
<SvgIcon name={bpmnIconName.value}></SvgIcon>
<div class='inline-block'>
<p class="mb-0 mb-1 text-[1.3em] font-bold text-black">{elementType.value}</p>
<p class="mb-0 pb-0 text-[1em] text-black">{bpmnName.value}</p>
</div>
</div>
展示效果如下:
插入的svg Dom
如下:
多说一句,这个插件大家根据需求选择是否使用,若SVG
实在过大过多还不如单次加载SVG
来的更好,并非什么都是越全越好,选择合适的更为重要!