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文件名

相关推荐
小小小小宇1 小时前
虚拟列表兼容老DOM操作
前端
悦悦子a啊1 小时前
Python之--基本知识
开发语言·前端·python
安全系统学习2 小时前
系统安全之大模型案例分析
前端·安全·web安全·网络安全·xss
涛哥码咖3 小时前
chrome安装AXURE插件后无效
前端·chrome·axure
OEC小胖胖3 小时前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
行云&流水3 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
Sally璐璐3 小时前
零基础学HTML和CSS:网页设计入门
前端·css
老虎06273 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
三水气象台4 小时前
用户中心Vue3网页开发(1.0版)
javascript·css·vue.js·typescript·前端框架·html·anti-design-vue
灿灿121384 小时前
CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
前端·css