文章目录
- 一、准备工作(在 Vue3 中使用 SVG)
- 二、封装 SVG
- 三、封装图标选择器
- 四、Demo
效果预览:
一、准备工作(在 Vue3 中使用 SVG)
本文参考: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>
二、封装 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>
四、Demo
<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>