如何在vue3+vite中使用svg-sprite-loader(SVG精灵图)

6,422 阅读2分钟

什么是svg-sprite-loader?

svg-sprite-loader 是一个插件,它可以帮助你将 SVG 图片拼接成 SVG Sprites(SVG雪碧图),放到页面中,其它地方通过 use 复用。它的工作原理是利用 svg 的 symbol 元素,将每个 icon 包括在 symbol 中,通过 use 元素使用该 symbol 。这样可以减少 HTTP 请求,提高页面加载速度 。
symbol和SVG Sprite又有什么关系呢?
  可以把SVG元素看成一个舞台,而symbol则是舞台上一个一个组装好的元件,这这些一个一个的元件就是我们即将使用的一个一个SVG图标。
对于一个集合了三个SVG图标的SVG元素的代码结构会是这样:

<svg>
    <symbol>
        <!-- 第1个图标路径形状之类代码 -->
    </symbol>
    <symbol>
        <!-- 第2个图标路径形状之类代码 -->
    </symbol>
    <symbol>
        <!-- 第3个图标路径形状之类代码 -->
    </symbol>
</svg>

你的每一个icon都对应着一个symbol元素。然后在你的html中,引入这样的svg, 随后通过use在任何你需要icon的地方指向symbol:

<svg>
    <use xlink:href="#symbolId"></use>
</svg>

如果还不是很懂得话可以看一下张老师得这篇文章未来必热:SVG Sprites技术介绍

引入依赖

npm install vite-plugin-svg-icons -D

配置vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'

export default defineConfig({
  plugins: [vue(),
  // 注册所有的svg文件生成svg雪碧图
  createSvgIconsPlugin({
    iconDirs: [path.resolve(process.cwd(), "src/assets/icons")], // icon存放的目录
    symbolId: "icon-[name]", // symbol的id
    inject: "body-last", // 插入的位置
    customDomId: "__svg__icons__dom__" // svg的id
  })],
  // 配置根路径
  resolve: {
    // ↓路径别名,主要是这部分
    alias: {
      "@": path.resolve(__dirname, "./src")
    }
  },
})
  • 在 main.ts 中引入注册脚本 import "virtual:svg-icons-register"
  • 如果报错没有 fast-glob包, 则是幽灵依赖没安装成功
  • 安装命令 npm install fast-glob -D即可

封装SvgIcon组件

<template>
  <svg :class="svgClass" aria-hidden="true">
    <use :xlink:href="iconName" />
  </svg>
</template>

<script setup lang='ts'>
import { computed } from 'vue'
const props = defineProps({
  iconClass: {
    type: String,
    required: true,
  },
  className: {
    type: String,
    default: () => '',
  },
})

const iconName = computed(() => {
  console.log(`#icon-${props.iconClass}`);
  return `#icon-${props.iconClass}`
})
const svgClass = computed(() => {
  return props.className ? 'svg-icon ' + props.className : 'svg-icon';
})

</script>
<style scoped lang="scss">
.svg-icon {
  fill: currentColor;
}
</style>

在src/assets/icons中创建一个index.ts文件,并在文件中全局注册SvgIcon组件 image.png 在main.ts中引入svg插件通过 use 注册

image.png

使用

    <nav>
        <div class="navigation-buttons">
            <svg-icon iconClass="arrow-left"/>
        </div>
    </nav>

就有效果啦 image.png