vue3+vite+ts 使用自定义svg图标(vite-plugin-svg-icons)

作用

自动注册svg图标,使svg图标在项目中能够被正确加载和使用。

使用教程

在vue3+vite+ts项目中使用。

安装依赖包

需要安装两个包,一个是vite-plugin-svg-icons,一个是fast-glob,fast-glob 是一个高性能的文件路径匹配库,它可以根据指定的 glob 模式(一种用于匹配文件路径的模式)快速查找文件系统中的文件。

vite-plugin-svg-icons 会使用 fast-glob 来查找指定目录下的所有 SVG 文件。

npm install vite-plugin-svg-icons@2.0.1 --save-dev
npm install fast-glob@3.3.2 --save-dev
配置插件

打开vite.config.ts文件,配置如下内容:

import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'

const pathSrc = path.resolve(__dirname, "src");

export default defineConfig({
  plugins: [
    createSvgIconsPlugin({
      iconDirs: [path.resolve(pathSrc, 'assets/icons')], // 你的 SVG 目录
      symbolId: 'icon-[dir]-[name]',
    }),
  ],
})
创建svg文件夹

在src→assets路径下创建icons文件夹,所有的自定义svg图标存储在该文件夹下。

创建svg图标组件

在src→components路径下创建SvgIcon文件夹,并在该文件夹下创建index.vue,内容如下:

<template>
  <svg
    aria-hidden="true"
    class="svg-icon"
    :style="'width:' + size + ';height:' + size"
  >
    <use :xlink:href="symbolId" :fill="color" />
  </svg>
</template>

<script setup lang="ts">
import {computed} from "vue";
const props = defineProps({
  prefix: {
    type: String,
    default: "icon",
  },
  iconClass: {
    type: String,
    required: false,
    default: "",
  },
  color: {
    type: String,
    default: "",
  },
  size: {
    type: String,
    default: "1em",
  },
});

const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`);
</script>

<style scoped>
.svg-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  overflow: hidden;
  vertical-align: -0.15em;
  outline: none;
  fill: currentcolor;
}
</style>

全局注册组件并导入虚拟模块

打开 main.ts 文件,添加如下内容:

import "virtual:svg-icons-register";
import SvgIcon from './components/SvgIcon/Index.vue'; 

const app = createApp(App);
app.component('svg-icon', SvgIcon);
声明虚拟模块

必须要执行这一步,否则在main.ts文件中配置【import "virtual:svg-icons-register"】这一行代码会报错,提示“找不到模块“virtual:svg-icons-register”或其相应的类型声明”。

在src→typings文件夹下创建vite-env.d.ts文件(文件夹可以自定义,也可以不创建文件夹,直接放在src目录下)。此文件是 TypeScript 的环境声明文件,用于告诉 TypeScript 如何解析特定模块。通过 declare module 语法,显式声明 Vite 插件生成的虚拟模块的类型,避免 TypeScript 的类型检查报错。

配置内容如下:

// src/typings/vite-env.d.ts
/// <reference types="vite/client" />

declare module 'virtual:svg-icons-register' {
    const content: string;
    export default content;
  }
  
declare module 'virtual:*' {
  const content: string;
  export default content;
}

注意:像.ts这类后缀文件需要在tsconfig.json或者tsconfig.app.json文件里的includes属性值里配置,如下所示

配置前:

{
  "include": ["src/**/*.ts","src/**/*.tsx", "src/**/*.vue"]
}

配置后:

{
  "include": ["src/**/*.ts","src/typings/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
  1. /// <reference types="vite/client" />
    • 引入 Vite 内置的客户端类型定义(包括 Vite 特有的模块和全局变量)。
    • 这是 Vite 项目的标准配置,用于支持如 import.meta.env 等特性。
  2. declare module 'virtual:svg-icons-register'
    • 显式声明 virtual:svg-icons-register 虚拟模块。
    • 告诉 TypeScript:该模块存在且默认导出一个字符串(content: string)。
  3. declare module 'virtual:*'
    • 使用通配符 (*) 声明所有以 virtual: 开头的虚拟模块。
    • 避免为每个虚拟模块单独写声明(如后续可能新增其他虚拟模块)。
使用svg图标

在vue页面中使用,例如用户登录页面中的账号和密码图标

<svg-icon icon-class="user" class="mx-2" />
<svg-icon icon-class="lock" class="mx-2" />  

这里的lock、user对应svg图标的名称。

posted @ 2025-05-07 15:57  相遇就是有缘  阅读(207)  评论(1)    收藏  举报