三十的博客

Vue3 + Vite 实现 SVG 图标组件自动加载

本文内容基于 AI 生成结果整理,可能包含不准确信息,仅供参考使用。
发布时间
阅读量 加载中...

前言

在 Vue 项目开发中,SVG 图标因其清晰的矢量特性和良好的可定制性而被广泛使用。手动引入和注册每个图标不仅繁琐,还容易出错。本文将介绍如何在 Vue3 + Vite 项目中使用 vite-plugin-svg-icons 插件实现 SVG 图标组件的自动加载和全局注册,提高开发效率。

开发环境

本文基于以下环境版本实现:

实现步骤

1. 安装插件

首先,使用 pnpm 安装 vite-plugin-svg-icons 插件:

bash
pnpm add vite-plugin-svg-icons -D

2. 配置 Vite

vite.config.ts 中添加插件配置:

ts
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import path from "path";

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    // SVG 图标自动加载配置
    createSvgIconsPlugin({
      // 指定图标文件夹路径
      iconDirs: [path.resolve(process.cwd(), "src/assets/icons")],
      // 指定图标 ID 的格式
      symbolId: "icon-[dir]-[name]",
    }),
  ],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
});

3. 创建 SVG 图标组件

src/components/SvgIcon 目录下创建 index.vue 文件,实现可复用的 SVG 图标组件:

vue
// src/components/SvgIcon/index.vue
<template>
  <!-- svg: 图标外层容器节点内部需要与 use 标签结合使用 -->
  <svg :style="{ width, height }">
    <!-- xlink:href 指定使用哪一个图标属性值务必为 #icon-图标名字 -->
    <!-- use 标签 fill 属性可以设置图标的颜色 -->
    <use :xlink:href="prefix + name" :fill="color"></use>
  </svg>
</template>

<script setup lang="ts">
defineProps({
  // 属性值前缀
  prefix: {
    type: String,
    default: "#icon-",
  },
  // 提供使用的图标名字
  name: String,
  // 接受父组件传递的颜色
  color: {
    type: String,
    default: "",
  },
  // 接受父组件传递的宽度
  width: {
    type: String,
    default: "16px",
  },
  // 接受父组件传递的高度
  height: {
    type: String,
    default: "16px",
  },
});
</script>

4. 组织 SVG 图标文件

src 目录下创建 icons 文件夹,并将 SVG 图标文件放入其中。可以根据图标类型创建子文件夹进行分类。

5. 全局注册组件

src/components 目录下创建 index.ts 文件,用于全局注册组件:

ts
// src/components/index.ts
import type { App } from "vue";
import SvgIcon from "@/components/SvgIcon/index.vue";
import Paginate from "@/components/Paginate/index.vue";

// 类型安全的注册函数
const registerGlobalComponents = (app: App) => {
  const components = {
    SvgIcon,
    Paginate,
  };

  Object.entries(components).forEach(([name, component]) => {
    app.component(name, component);
  });
};

export default {
  install: registerGlobalComponents,
};

6. 在 main.ts 中引入并使用

src/main.ts 中引入 SVG 图标注册脚本和全局组件:

ts
// src/main.ts
import { createApp } from "vue";
import App from "./App.vue";

// 引入 SVG 图标注册脚本
import "virtual:svg-icons-register";

// 引入自定义插件对象:注册整个项目全局组件
import globalComponents from "@/components";

const app = createApp(App);

// 安装自定义插件
app.use(globalComponents);

app.mount("#app");

使用方法

在项目的任何组件中,可以直接使用全局注册的 SvgIcon 组件:

vue
<template>
  <div class="example">
    <!-- 基础使用 -->
    <SvgIcon name="common-user" />

    <!-- 自定义颜色和大小 -->
    <SvgIcon name="menu-home" color="#42b983" width="24px" height="24px" />

    <!-- 使用不同目录下的图标 -->
    <SvgIcon name="other-settings" />
  </div>
</template>
ℹ️ 注意
name 属性的值为图标文件的路径(不包含扩展名),格式为 [目录名]-[文件名],与 vite.config.ts 中配置的 symbolId 格式相对应。

原理说明

  1. vite-plugin-svg-icons 插件会在 Vite 构建过程中,自动扫描指定目录下的所有 SVG 文件
  2. 插件将这些 SVG 文件转换为 Symbol 元素,并注入到页面的 body
  3. 我们创建的 SvgIcon 组件通过 use 标签引用这些 Symbol 元素,实现图标显示
  4. 通过全局注册组件,我们可以在项目的任何地方直接使用 SvgIcon 组件

扩展与优化

  1. 动态导入图标:如果项目图标数量很多,可以考虑按需动态导入,减少初始加载体积
  2. 图标预览:可以使用插件提供的预览功能,在开发过程中方便查看所有图标
  3. 自定义图标处理:可以通过插件配置自定义 SVG 的处理方式,如压缩、优化等
  4. 类型定义:为图标名称添加类型定义,提供更好的 TypeScript 支持

总结

通过 vite-plugin-svg-icons 插件,我们可以轻松实现 SVG 图标组件的自动加载和全局注册,避免了手动引入图标的繁琐工作。这种方式不仅提高了开发效率,还使得图标管理更加清晰和规范。

#Vue3 #Svg