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

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

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

准备svg文件

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

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

安装依赖

bash 复制代码
pnpm add -D unocss @iconify/utils glob

配置文件

vite.config.ts

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

uno.config.ts

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/wind3
    presetWind3(),
    // 预设图标
    presetIcons({
      warn: true,
      prefix: ['i-'],
      // 设置全局图标默认属性
      extraProperties: {
        width: "1em",
        height: "1em",
        display: "inline-block",
      },
      // 注册本地 svg 图标集合
      collections,
    }),
  ],
  safelist: generateSafeList(), // 动态生成 `safelist`
});

使用图标

html 复制代码
<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文件名

相关推荐
W.A委员会1 小时前
CSS中的单位
css·css3·html5
donecoding2 小时前
一个 sudo 引发的血案:npm 全局包权限错乱彻底修复
前端·node.js·前端工程化
风骏时光牛马2 小时前
Raku正则匹配与数据批量处理实操案例
前端
nbwenren2 小时前
2026实测:Gemini 3 镜像站视觉能力实践——拍照原型图,一键生成 HTML+CSS 代码
前端·css·html
Lee川2 小时前
Prisma 实战指南:像搭积木一样设计古诗词数据库
前端·数据库·后端
jinanwuhuaguo2 小时前
(第二十九篇)OpenClaw 实时与具身的跃迁——从异步孤岛到数字世界的“原住民”
前端·网络·人工智能·重构·openclaw
广州华水科技3 小时前
深度测评2026年单北斗GNSS位移监测系统推荐,与高口碑变形监测设备一同引领行业新风尚
前端
Alice-YUE3 小时前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript
是上好佳佳佳呀5 小时前
【前端(十一)】JavaScript 语法基础笔记(多语言对比)
前端·javascript·笔记