「vue3-element-admin」告别 vite-plugin-svg-icons!用 @unocss/preset-icons 加载本地 SVG 图标

🚀 作者主页: 有来技术
🔥 开源项目: youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template
🌺 仓库主页: GitCode︱ Gitee ︱ Github
💖 欢迎点赞 👍 收藏 ⭐评论 📝 如有错误敬请纠正!

目录

    • 📝 前言背景
    • 🔍 问题分析:插件停止维护,依赖过时
    • 🛠️ 解决方案:使用 `@unocss/preset-icons`
      • 1️⃣ 安装依赖
      • 2️⃣ 配置 `uno.config.ts`
      • 3️⃣ 使用图标
    • 🏆 总结

📝 前言背景

在此之前,开源项目 vue3-element-admin 使用 vite-plugin-svg-icons 管理和加载从iconfont 等网站下载到本地 SVG 图标。但由于该插件 已停止维护,部分依赖逐渐过时,可能影响未来兼容性,因此需要迁移到更稳定的方案。

🔍 问题分析:插件停止维护,依赖过时

在项目中执行 pnpm install 时,我们发现控制台出现了以下 废弃依赖警告

 WARN  10 deprecated subdependencies found: fstream@1.0.12, glob@7.2.3, inflight@1.0.6, lodash.isequal@4.5.0, resolve-url@0.2.1, rimraf@2.7.1, source-map-resolve@0.5.3, source-map-url@0.4.1, stable@0.1.8, urix@0.1.0


通过 pnpm why urix 追踪依赖来源,发现 这些过时依赖属于 vite-plugin-svg-icons,而 vite-plugin-svg-icons 最近一次更新是在 2022 年 1 月 29 日,其被维护的概率很小。

为了确保长期稳定性,决定 @unocss/preset-icons 替代 vite-plugin-svg-icons


🛠️ 解决方案:使用 @unocss/preset-icons

@unocss/preset-icons 是 UnoCSS 提供的图标预设,支持从 本地和在线图标库 加载图标。它相比 vite-plugin-svg-icons 具有以下优势:

  • 无需额外安装unocss 自带 @unocss/preset-icons,减少额外依赖;
  • 直接支持 Iconify 图标集,可以同时使用 本地 SVG 和在线图标
  • 按需加载,无需手动导入,减少构建体积。

官方文档:https://unocss.nodejs.cn/presets/icons

1️⃣ 安装依赖

使用 FileSystemIconLoader 从文件系统加载本地 SVG 图标,需要安装 @iconify/utils 作为开发依赖:

pnpm add -D @iconify/utils

⚠️ 注意:@unocss/preset-icons 已包含在 unocss 中,无需单独安装。

2️⃣ 配置 uno.config.ts

在 vue3-element-admin 项目中,应在 uno.config.ts 配置,而非 vite.config.ts

完整配置如下:

import { defineConfig, presetUno } from "unocss";
import presetIcons from "@unocss/preset-icons";
import { FileSystemIconLoader } from "@iconify/utils/lib/loader/node-loaders";
import fs from "fs";// 本地 SVG 图标存放目录
const iconsDir = "./src/assets/icons";// 读取本地 SVG 目录,自动生成 `safelist`
const generateSafeList = () => {try {return fs.readdirSync(iconsDir).filter((file) => file.endsWith(".svg")).map((file) => `i-svg:${file.replace(".svg", "")}`);} catch (error) {console.error("无法读取图标目录:", error);return [];}
};export default defineConfig({presets: [presetIcons({// 设置全局图标默认属性extraProperties: {width: "1em",height: "1em",display: "inline-block",},// 注册本地 SVG 图标集合collections: {// svg 是图标集合名称,使用 `i-svg:图标名` 调用  svg: FileSystemIconLoader(iconsDir, (svg) => {// 如果 SVG 文件未定义 `fill` 属性,则默认填充 `currentColor`  // 这样图标颜色会继承文本颜色,方便在不同场景下适配  return svg.includes('fill="')? svg: svg.replace(/^<svg /, '<svg fill="currentColor" ');}),},}),],safelist: generateSafeList(), // 动态生成 `safelist`
});

与 官方配置 有两点不同

  1. 使用 safelist 解决动态图标加载问题

    UnoCSS 采用 按需扫描 机制,仅能解析静态类名,而 vue3-element-admin 的菜单图标是动态加载的,例如:

    <template><div v-for="item in menuItems" :key="item.name"><div :class="`i-svg:${item.icon}`"></div>{{ item.name }}</div>
    </template><script setup lang="ts">const menuItems = [{ name: "首页", icon: "home" },{ name: "设置", icon: "settings" },];
    </script>
    

    由于 unocss 无法在编译阶段解析动态绑定的 :class,导致图标不会被正确加载。因此,我们通过 扫描 src/assets/icons 目录并动态生成 safelist,确保所有本地 SVG 图标类名都能被 unocss 识别。

  2. 优化 fill 处理,支持多彩图标

    为了避免默认 fill="currentColor" 影响多彩图标的渲染,我们仅在 SVG 未定义 fill 时才自动补充:

    if (!svg.includes('fill="')) {return svg.replace(/^<svg /, '<svg fill="currentColor" ');
    }
    

3️⃣ 使用图标

uno.config.ts 中,通过 collections 注册了名为 svg 的本地 SVG 图标集合,并使用 FileSystemIconLoader 读取 src/assets/icons 目录下的 SVG 文件。因此,可直接使用 i-svg:图标名称 调用。

示例:

src/assets/icons/home.svg → i-svg:home
<template><!-- 默认尺寸 1em,颜色继承父级 text 颜色 --><div class="i-svg:home"></div><!-- 自定义颜色和尺寸 --><div class="i-svg:home text-xl text-blue-500"></div>   
</template>

最终效果如下:

🏆 总结

由于 vite-plugin-svg-icons 停止更新,且部分依赖过时,我们成功迁移到 @unocss/preset-icons,并针对 vue3-element-admin 进行了优化和改造
使用 @unocss/preset-icons 统一管理本地 SVG 图标
无需手动安装 @unocss/preset-iconsunocss 已内置
通过 safelist 自动读取 src/assets/icons,支持动态菜单图标
减少额外依赖,提高项目长期可维护性

开源项目地址:vue3-element-admin

🚀 通过这次改造,我们实现了 更灵活、现代的 SVG 图标管理方式,欢迎大家尝试并优化自己的项目!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/69318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#中深度解析BinaryFormatter序列化生成的二进制文件

C#中深度解析BinaryFormatter序列化生成的二进制文件 BinaryFormatter序列化时,对象必须有 可序列化特性[Serializable] 一.新建窗体测试程序BinaryDeepAnalysisDemo,将默认的Form1重命名为FormBinaryDeepAnalysis 二.新建测试类Test Test.cs源程序如下: using System; us…

深度学习在医疗影像分析中的应用

引言 随着人工智能技术的快速发展&#xff0c;深度学习在各个领域都展现出了巨大的潜力。特别是在医疗影像分析中&#xff0c;深度学习的应用不仅提高了诊断的准确性&#xff0c;还大大缩短了医生的工作时间&#xff0c;提升了医疗服务的质量。本文将详细介绍深度学习在医疗影像…

计算机领域QPM、TPM分别是什么并发指标,还有其他类似指标吗?

在计算机领域&#xff0c;QPM和TPM是两种不同的并发指标&#xff0c;它们分别用于衡量系统处理请求的能力和吞吐量。 QPM&#xff08;每分钟请求数&#xff09; QPM&#xff08;Query Per Minute&#xff09;表示每分钟系统能够处理的请求数量。它通常用于衡量系统在单位时间…

【安当产品应用案例100集】036-视频监控机房权限管理新突破:安当windows操作系统登录双因素认证解决方案

一、机房管理痛点&#xff1a;权限失控下的数据泄露风险 在智慧城市与数字化转型浪潮下&#xff0c;视频监控系统已成为能源、金融、司法等行业的核心安防设施。然而&#xff0c;传统机房管理模式中&#xff0c;值班人员通过单一密码即可解锁监控画面的操作漏洞&#xff0c;正…

Unity抖音云启动测试:如何用cmd命令行启动exe

相关资料&#xff1a;弹幕云启动&#xff08;原“玩法云启动能力”&#xff09;_直播小玩法_抖音开放平台 1&#xff0c;操作方法 在做云启动的时候&#xff0c;接完发现需要命令行模拟云环境测试启动&#xff0c;所以研究了下。 首先进入cmd命令&#xff0c;CD进入对应包的文件…

< OS 有关 > 利用 google-drive-ocamlfuse 工具,在 Ubuntu 24 系统上 加载 Google DRIVE 网盘

Created by Dave On 8Feb.2025 起因&#xff1a; 想下载 StableDiffusion&#xff0c;清理系统文件时把 i/o 搞到 100%&#xff0c;已经删除到 apt 缓存&#xff0c;还差 89MB&#xff0c;只能另想办法。 在网上找能不能挂在 Google 网盘&#xff0c;百度网盘&#xff0c;或 …

【LITS游戏——暴力DFS+剪枝优化】

题目 代码 #include <bits/stdc.h> using namespace std; using pll pair<int, int>; #define x first #define y second const int N 51; pll d[4][4][4] {{{{0, 0}, {1, 0}, {2, 0}, {2, 1}}, {{0, 0}, {1, 0}, {1, -1}, {1, -2}}, {{0, 0}, {0, 1}, {1, 1},…

Redisson全面解析:从使用方法到工作原理的深度探索

文章目录 写在文章开头详解Redisson基本数据类型基础配置字符串操作列表操作映射集阻塞队列延迟队列更多关于Redisson详解Redisson 中的原子类详解redisson中的发布订阅模型小结参考写在文章开头 Redisson是基于原生redis操作指令上进一步的封装,屏蔽了redis数据结构的实现细…

用Python进行websocket接口测试

这篇文章主要介绍了用Python进行websocket接口测试&#xff0c;帮助大家更好的理解和使用python&#xff0c;感兴趣的朋友可以了解下 我们在做接口测试时&#xff0c;除了常见的http接口&#xff0c;还有一种比较多见&#xff0c;就是socket接口&#xff0c;今天讲解下怎么用P…

【RocketMQ 存储】- 同步刷盘服务 GroupCommitService

文章目录 1. 前言2. 参数3. 队列相关4. 核心逻辑 run4.1 waitForRunning4.2 doCommit4.3 flush 5. 小结 本文章基于 RocketMQ 4.9.3 1. 前言 RocketMQ 存储部分系列文章&#xff1a; 【RocketMQ 存储】- RocketMQ存储类 MappedFile【RocketMQ 存储】- 一文总结 RocketMQ 的存…

基于yolov11的阿尔兹海默症严重程度检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv11的阿尔兹海默症严重程度检测系统是一种创新的医疗辅助工具&#xff0c;旨在通过先进的计算机视觉技术提高阿尔兹海默症的早期诊断和病情监测效率。阿尔兹海默症是一种渐进性的神经退行性疾病&#xff0c;通常表现为认知障碍、记忆丧失和语言障碍等症状…

IDEA编写SpringBoot项目时使用Lombok报错“找不到符号”的原因和解决

目录 概述|背景 报错解析 解决方法 IDEA配置解决 Pom配置插件解决 概述|背景 报错发生背景&#xff1a;在SpringBoot项目中引入Lombok依赖并使用后出现"找不到符号"的问题。 本文讨论在上述背景下发生的报错原因和解决办法&#xff0c;如果仅为了解决BUG不论原…

【异常解决】在idea中提示 hutool 提示 HttpResponse used withoud try-with-resources statement

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

搜维尔科技:提供人形机器人传感器的应用案例分析

视觉传感器 • 家庭服务场景&#xff1a;在家庭清洁机器人中&#xff0c;视觉传感器可以识别家具、障碍物的位置和形状&#xff0c;规划清洁路径&#xff0c;避开桌椅、宠物玩具等。如小米扫地机器人&#xff0c;通过视觉传感器与算法结合&#xff0c;能构建房间地图&#xff…

虹科波形小课堂 | 三分钟掌握车辆相对压缩测试!不拆发动机、不测缸压就能判断故障缸!

不拆发动机、不测缸压&#xff0c;只测个电流也能知道哪个缸压缩有问题&#xff1f;没错&#xff01;做个相对压缩测试&#xff0c;测下起动电流就行&#xff0c;简单又实用&#xff01;今天&#xff0c;从原理到方法&#xff0c;几分钟教会你&#xff01; 我们都知道&#xf…

自然语言处理NLP_[1]-NLP入门

文章目录 1.自然语言处理入门1. 什么是自然语言处理2.自然语言处理的发展简史3 自然语言处理的应用场景1. **机器翻译**2. **文本分类**3. **情感分析**4. **问答系统**5. **文本生成**6. **信息抽取**7. **语音识别与合成**8. **文本摘要**9. **搜索引擎优化**10. **聊天机器人…

无限使用Cursor

原理&#xff1a;运行程序获得15天的免费试用期&#xff0c;重新运行程序重置试用期&#xff0c;实现无限使用。免费的pro账号&#xff0c;一个月有250的高级模型提问次数。 前提&#xff1a;已安装cursor cursor-vip工具&#xff1a;https://cursor.jeter.eu.org?p95d60efe…

LIMO:少即是多的推理

25年2月来自上海交大、SII 和 GAIR 的论文“LIMO: Less is More for Reasoning”。 一个挑战是在大语言模型&#xff08;LLM&#xff09;中的复杂推理。虽然传统观点认为复杂的推理任务需要大量的训练数据&#xff08;通常超过 100,000 个示例&#xff09;&#xff0c;但本文展…

一种基于Leaflet.Legend的图例动态更新方法

目录 前言 一、场景再现 1、需求描述 2、核心方法介绍 3、存在的问题 二、问题解决 1、重复解决办法 2、图例不展示解决办法 3、成果展示 三、总结 前言 在当今数字化时代&#xff0c;地理信息系统&#xff08;GIS&#xff09;技术已经广泛应用于各个领域&#xff0c;…

【AI时代】使用ollama私有化部署deepseek的过程及问题记录

文章目录 说明下载模型通过ollama下载通过modelscope下载 部署open-webui问题记录临时目录空间不足单机多卡部署后台启动 说明 对于DeepSeek的私有化部署&#xff0c;现在网上已经有很全面的资料了&#xff0c;本文主要记录部署以及部署过程中遇到的问题。目前对于这些问题&am…