1. 使用方式
页面中直接写标签,myicon是svg图片文件名,不需要引入。myicon文件放在指定的svg目录中即可。
<svg-icon icon-class="myicon"
2. 实现方式
(1)新建vite文件夹,建一个plugins文件夹,新建一个svg-icon.js文件,内容如下
// 用到插件 "vite-plugin-svg-icons": "2.0.1" 自行下载依赖
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'; import path from 'path';// 此函数用于创建 SVG 图标插件实例 export default function createSvgIcon(isBuild) {// 返回一个通过 createSvgIconsPlugin 创建的插件实例return createSvgIconsPlugin({// iconDirs 是一个数组,指定了包含 SVG 图标的目录路径// 通过 path.resolve 和 process.cwd 获取当前工作目录,然后指向'src/assets/icons/svg'目录iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')],// symbolId 定义了生成的 SVG 图标的唯一标识符格式symbolId: 'icon-[dir]-[name]',// svgoOptions 根据传入的 isBuild 参数确定// 如果 isBuild 为 true,可能在构建阶段传递一些优化 SVG 的选项给 svgo svgoOptions: isBuild,}); }
(2)在plugins文件夹中,新建一个index.js文件, 引入刚才创建的svg-icon.js
import vue from '@vitejs/plugin-vue'; import createSvgIcon from './svg-icon';// 此函数用于创建 Vite 插件数组 export default function createVitePlugins(viteEnv, isBuild = false) {// 定义一个数组来存储 Vite 插件const vitePlugins = [vue()];// 将创建 SVG 图标插件的函数结果添加到插件数组中 vitePlugins.push(createSvgIcon(isBuild));// 如果是构建阶段(isBuild 为 true),将压缩插件函数的结果添加到插件数组中isBuild && vitePlugins.push(...createCompression(viteEnv));// 返回 Vite 插件数组return vitePlugins; }
(3) 在vue.config.js文件中配置,如图
// 引入
import createVitePlugins from './vite/plugins'; plugins: createVitePlugins(env, command === 'build'), // 用于指定要应用于项目构建过程的插件列表
(4)在compenonts文件夹中建一个SvgIcon文件夹,新建index.js文件
import * as components from '@element-plus/icons-vue';// 默认导出 export default {// install 方法用于将插件安装到 Vue 应用实例中install: (app) => {// 遍历从 '@element-plus/icons-vue' 导入的所有组件for (const key in components) {// 获取当前遍历到的组件的配置信息const componentConfig = components[key];// 将当前组件注册到 Vue 应用实例中,使用组件的名称作为注册名 app.component(componentConfig.name, componentConfig);}}, };
(5) 在SvgIcon文件夹中,新建index.vue文件
<template>
<!-- SVG 元素,用于显示图标 -->
<svg :class="svgClass" aria-hidden="true">
<!-- 使用 xlink:href 属性引用图标 -->
<use :xlink:href="iconName" :fill="color" />
</svg>
</template>
<script>
export default defineComponent({
props: {
// 接收传递进来的图标类名,类型为字符串,且是必需的属性
iconClass: {
type: String,
required: true,
},
// 接收传递进来的额外的类名,类型为字符串,默认值为空字符串
className: {
type: String,
default: '',
},
// 接收传递进来的颜色值,类型为字符串,默认值为空字符串
color: {
type: String,
default: '',
},
},
setup(props) {
return {
// 计算属性,根据传递进来的 iconClass 生成图标名称
iconName: computed(() => `#icon-${props.iconClass}`),
// 计算属性,根据是否有 className 属性来生成 SVG 的类名
svgClass: computed(() => {
if (props.className) {
return `svg-icon ${props.className}`;
}
return 'svg-icon';
}),
};
},
});
</script>
<style scope lang="scss">
.sub-el-icon,
.nav-icon {
display: inline-block;
font-size: 15px;
margin-right: 12px;
position: relative;
}
.svg-icon {
width: 1.15em;
height: 1.15em;
position: relative;
fill: currentColor;
vertical-align: -2px;
}
</style>
(6)main.js配置
import "virtual:svg-icons-register"; import SvgIcon from "@/components/SvgIcon"; import elementIcons from "@/components/SvgIcon/svgicon";app.use(elementIcons); app.component('svg-icon', SvgIcon);