本文参考:https://blog.csdn.net/houtengyang/article/details/129043100
安装插件
npm i vite-plugin-svg-icons
配置插件
修改 vite.config.js
import {resolve} from 'path'
import {createSvgIconsPlugin} from 'vite-plugin-svg-icons';
export default defineConfig({
plugins: [
vue(),
createSvgIconsPlugin({
iconDirs: [resolve(process.cwd(), 'public')], // svg 文件存放位置
symbolId: 'icon-[name]', // 指定symbolId格式
}),
],
})
注意:我的 svg 存放路径是根目录下的
./public
,多数情况下放在./src/assets
。
修改 main.js
,增加一行代码。
import 'virtual:svg-icons-register'
使用示例
<svg aria-hidden="true" style="width: 14px; height: 14px">
<use :href="`#icon-${menu.icon}`" />
svg>
将上述使用示例封装为组件。
在 ./src/components
下创建 Icon.vue
<script setup>
const props = defineProps({
prefix: {type: String, default: 'icon'},
name: {type: String, required: true},
color: {type: String},
size: {type: String, default: '1em'}
});
const symbolId = computed(() => `#${props.prefix}-${props.name}`);
</script>
<template>
<svg aria-hidden="true" class="svg-icon" :style="'vertical-align:middle;width:' + size + ';height:' + size">
<use :href="symbolId" :fill="color"/>
</svg>
</template>
<style scoped>
.svg-icon {
overflow: hidden;
fill: currentColor;
}
</style>
svg
样式里添加了vertical-align:middle
使用示例
<Icon :name="vite">Icon>
在 ./src/components
下创建 IconSelect.vue
<script setup>
import Icon from "@/components/Icon.vue";
const props = defineProps({
modelValue: {type: String, default: ''},
});
const value = ref(props.modelValue)
const icons = [];
const modules = import.meta.glob('../../public/**/*.svg');
for (const path in modules) {
const name = path.split('public/')[1].split('.svg')[0];
icons.push(name);
}
const emits = defineEmits(['update:modelValue']);
const change = (name) => {
emits('update:modelValue', name)
}
</script>
<template>
<el-select v-model="value" @change="change" filterable clearable placeholder="Select Icon">
<el-option v-for="item in icons" :key="item" :label="item" :value="item">
<span style="float: left">
<Icon :name="item" size="30px"></Icon>
</span>
<span style="float: right;color: var(--el-text-color-secondary);font-size: 13px;">
{{ item }}
</span>
</el-option>
</el-select>
<Icon :name="value" size="32px" style="padding-left: 10px"></Icon>
</template>
import.meta.glob('../../public/**/*.svg')
用于获取./public
路径下各个层级的 .svg 文件。
使用示例(在表单中使用):
<el-form-item label="Icon">
<IconSelect v-model="obj.icon">IconSelect>
el-form-item>
<script setup>
import IconSelect from "@/components/IconSelect.vue";
import Icon from "@/components/Icon.vue";
const symbol = ref('')
</script>
<template>
{{ symbol }}
<Icon :name="symbol" size="32px" style="padding-left: 10px"></Icon>
<br/>
<IconSelect v-model="symbol"/>
</template>