svgicon实现效果图
vite-plugin-svg-icons 是一款专为Vite构建工具设计的SVG图标管理插件,其核心价值在于通过自动化雪碧图生成和组件化方案,解决前端项目中SVG图标管理混乱、重复请求等痛点。
1.下载依赖 vite-plugin-svg-icons
pnpm i vite-plugin-svg-icons -D
2.配置vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'node:path'
import process from 'node:process'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
// 指定 symbolId 格式
symbolId: 'icon-[dir]-[name]',
svgoOptions: true,
})
],
})
3.创建Svg组件
<template>
<svg
aria-hidden="true"
:class="svgClass"
v-bind="$attrs"
:style="{ color, fill: color, width: iconSize, height: iconSize }"
>
<use :xlink:href="iconName"></use>
</svg>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
name: {
type: String,
default: '',
required: true
},
color: {
type: String,
default: ''
},
size: {
type: [String, Number],
default: 20
}
})
// 判断传入的值是否带有单位,如果没有就默认用px单位
const getUnitValue = (value) => {
return /(px|em|rem|%)$/.test(value.toString()) ? value : `${value}px`
}
const iconSize = computed(() => {
return getUnitValue(props.size)
})
const iconName = computed(() => `#icon-${props.name}`)
const svgClass = computed(() => {
return props.name ? `svg-icon icon-${props.name}` : 'svg-icon'
})
</script>
<style scoped>
.svg-icon {
width: auto;
height: auto;
vertical-align: middle;
flex-shrink: 0;
}
</style>
4.main.js引入'virtual:svg-icons-register'
import 'virtual:svg-icons-register'
5.使用组件
<template>
<div class="icon-container">
<div v-for="iconName in iconNames" :key="iconName" class="icon-item">
<SvgIcon :name="iconName" :size="20" />
<span>{{ iconName }}</span>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import SvgIcon from './components/SvgIcon/index.vue'
function getAllIconNames() {
const svgModules = import.meta.glob('./assets/icons/*.svg', { eager: true })
// 提取文件名(不带扩展名)
return Object.keys(svgModules).map(path => {
const fileName = path.split('/').pop()
return fileName.replace('.svg', '')
})
}
const iconNames = ref([])
onMounted(() => {
iconNames.value = getAllIconNames()
})
</script>
<style scoped>
.icon-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 16px;
padding: 16px;
}
.icon-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 8px;
border: 1px solid #eee;
border-radius: 4px;
}
.icon-item span {
font-size: 12px;
text-align: center;
}
</style>