当前位置: 首页 > news >正文

Vue3+TS中svg图标的使用-@unocss/preset-icons

@unocss/preset-icons 是 UnoCSS 提供的图标预设,支持从 本地和在线图标库 加载图标,本文介绍本地图标库的使用

从 https://blog.csdn.net/u013737132/article/details/145499595 得知vite-plugin-svg-icons 插件停止维护,依赖过时,便整理替代品

准备svg文件

src/assets/icons下随意创建文件夹custom,menu

从网络上下载svg文件复制到两个文件夹下

安装依赖

pnpm add -D unocss @iconify/utils glob

配置文件

vite.config.ts

...
import vue from '@vitejs/plugin-vue'
// 导入Unocss插件
import Unocss from 'unocss/vite'
...
export default defineConfig({plugins: [vue(),// 注册Unocss插件Unocss(),]
})

uno.config.ts

import { defineConfig, presetIcons, presetWind3 } from "unocss";
import { FileSystemIconLoader } from "@iconify/utils/lib/loader/node-loaders";
import { globSync } from 'glob'
import path from 'node:path'/*** 获取 src/assets/icons/ 目录下的所有 svg图标文件* 实际只适用 icons的下一级目录,再下级目录不支持*/
const iconsDirPattern = "./src/assets/icons/**/*.svg";
const files = globSync(iconsDirPattern, { nodir: true }) // nodir:true 不匹配目录,只匹配文件
// 读取本地 SVG 目录,获取所有 svg 图标,并按照文件夹分类
/*** 返回数据格式* {*   menu: [ 'i-menu:home' ],*   custom: [*     'i-custom:welcome',*     'i-custom:refresh',*     'i-custom:phone',*     'i-custom:logout',*     'i-custom:lock',*     'i-custom:loading',*     'i-custom:juejin',*     'i-custom:home',*     'i-custom:full-screen',*     'i-custom:exit-full',*     'i-custom:copyright'*   ]* }*/
function getIcons() {const icons = {}files.forEach((filePath) => {const fileName = path.basename(filePath) // 获取文件名,包括后缀const fileNameWithoutExt = path.parse(fileName).name // 获取去除后缀的文件名const folderName = path.basename(path.dirname(filePath)) // 获取文件夹名if (!icons[folderName]) {icons[folderName] = []}icons[folderName].push(`i-${folderName}:${fileNameWithoutExt}`)})return icons
}
const icons = getIcons()
/*** 读取本地 SVG 目录,获取所有 svg 图标,并按照文件夹分类* 返回数据格式* collections {*   menu: [AsyncFunction (anonymous)],*   custom: [AsyncFunction (anonymous)]* }*/
const collections = Object.fromEntries(Object.keys(icons).map(item => [item,FileSystemIconLoader(`src/assets/icons/${item}`, (svg) => {return svg.includes('fill="')? svg: svg.replace(/^<svg /, '<svg fill="currentColor" ');})
]))/*** 使用安全列表,在UnoCSS中使用动态生成的className名称* 提前声明那些动态生成的类名,以确保它们在最终的CSS中被包含* 返回数据格式* [*   'i-menu:home',*   'i-custom:welcome',*   'i-custom:refresh',*   'i-custom:phone',*   'i-custom:logout',*   'i-custom:lock',*   'i-custom:loading',*   'i-custom:juejin',*   'i-custom:home',*   'i-custom:full-screen',*   'i-custom:exit-full',*   'i-custom:copyright'* ]*/
const generateSafeList = () => {return Object.keys(icons).flatMap((item) => icons[item])
};export default defineConfig({presets: [// https://unocss.dev/presets/wind3presetWind3(),// 预设图标presetIcons({warn: true,prefix: ['i-'],// 设置全局图标默认属性extraProperties: {width: "1em",height: "1em",display: "inline-block",},// 注册本地 svg 图标集合collections,}),],safelist: generateSafeList(), // 动态生成 `safelist`
});

使用图标

<template><div class="home"><h2>home</h2>测试preset-icons<i class="i-custom:exit-full text-#0033cc text-2xl" /><i class="i-menu:refresh" /><i class="i-custom:juejin text-red text-[50px]" /><i class="i-custom:lock hover:text-sky " /></div>
</template><script setup lang="ts">
</script><style scoped></style>

i-: 固定前缀

menucustom: 文件夹名

exit-fullrefresh等: svg文件名

相关文章:

  • 【深度学习】LoRA:低秩适应性微调技术详解
  • 第33周JavaSpringCloud微服务 电商进阶开发
  • VSCode连服务器一直处于Downloading
  • 多骨干、多融合:RT-DETR 如何解锁主干网络新姿势?
  • 面试网络基础知识 — IP地址
  • 聚能芯半导体禾润一级代理HT7886开关限流降压变换器 5V – 100V 的宽输入电压3.5A 开关限流降压变换器
  • USB 共享神器 VirtualHere 局域网内远程使用打印机与扫描仪
  • 丰富多样功能的小白工具,视频提取音频,在线使用,无需下载软件
  • QEMU源码全解析 —— 块设备虚拟化(21)
  • 【Pandas】pandas DataFrame div
  • 三网通电玩城平台系统结构与源码工程详解(二):Node.js 服务端核心逻辑实现
  • SAS宏核心知识与实战应用
  • MCP(3):在CherryStudio中使用MCPServer
  • HTTP 请求头与请求体:数据存储的底层逻辑与实践指南
  • 第 2.1 节: 机器人仿真环境选择与配置 (Gazebo, MuJoCo, PyBullet)
  • 映射(Mapping)和地址(Address)
  • 创建表结构
  • UiPath API 调用文档
  • \r在C语言中是什么意思(通俗易懂,附带实例)
  • 算力网络的早期有关论文——自用笔记
  • 钟芳玲|戴耳环的莎士比亚
  • 直播中抢镜“甲亢哥”的翁东华卸任了!此前任文和友小龙虾公司董事
  • 全国人大常委会启动工会法执法检查
  • 事故调查报告:东莞一大楼装修项目去年致1人死亡,系违规带电作业
  • 江苏一季度实现地区生产总值3.3万亿元,同比增长5.9%
  • 郑州卫健委通报郑飞医院“血液净化”问题:拟撤销该院血液净化技术备案