什么是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组件
在main.ts中引入svg插件通过 use 注册
使用
<nav>
<div class="navigation-buttons">
<svg-icon iconClass="arrow-left"/>
</div>
</nav>
就有效果啦