前言
- 如果在一个项目中有很多
png、jpg
等等格式的图片,我们一般会将这些零散的图片合成一张 精灵图 ,通过背景图片的定位去使用不同的图片; - 如果一个项目使用到的图标绝大部分是
svg
格式的,为了简化使用,我们应该怎么办呢?- 下面就来说道说道;
一、svg简介
- 什么是SVG ?
- SVG 指可伸缩矢量图形(Scalable Vector Graphics);
- SVG 用来定义网络的基于矢量的图形;
- SVG 使用 XML 格式定义图形;
- SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失;
- SVG 是万维网联盟的标准;
- SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体;
SVG
于 2003年1月14日 成为 W3C 推荐标准;svg
格式的图片:- 它是
xml
格式的;
- 它是
- 如果一个项目中有很多的
svg
格式的图片,我们可以打包成svg
地图 对不同的svg
格式的图片进行使用;
二、打包成svg地图
-
简单来说,
svg
地图 就是另一种形式的 精灵图; -
将
svg
格式的图片打包成svg
地图 需要使用到vite-plugin-svg-icons
这个插件; -
下载 :
pnpm add vite-plugin-svg-icons -D
;
-
配置 :
-
目标文件:
vite.config.ts
;
ts// 导入插件 import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' // 导入 path(帮助我们生成路径) import path from 'path' export default () => { return { plugins: [ // ... 其他的插件配置 // 使用插件 createSvgIconsPlugin({ // 指定需要缓存的图标文件夹 - 'src/icons' // 就是说我们需要生成 svg地图 的所有 svg图标 在哪个文件夹下 // 我是放在 src/icons 下面,大家根据自己的文件夹写就可以了; iconDirs: [path.resolve(process.cwd(), 'src/icons')], }) // ... 其他的插件配置 ], } }
- 我所有的
svg
图标都放在这块:
-
在
main.ts
中注入脚本 :ts// 导入 svg地图 import 'virtual:svg-icons-register';
三、基础使用
-
打包成
svg
地图之后,所有的svg
格式图片的代码合在一块了; -
合在一块之后,每个
svg
标签上都会有个id
属性; -
使用步骤 :
- 在需要使用
svg
图片的地方,先添加一个svg
标签; - 在
svg
标签 内部再使用use
标签; - 给
use
标签的href
属性 的属性值设置为#icon-存放当前使用svg的文件夹-svg名字(不带.svg后缀)
的格式即可;
- 在需要使用
-
❗ 注意 :
- 给
use
标签的href
属性赋值的时候#icon-
是固定写法;
- 给
-
示例:
html<svg aria-hidden="true"> <use href="#icon-consult-alipay"></use> </svg>
-
我们可以看到,所有的
svg
都被导入进来了,并且都是有id
属性的,所有的id
属性都带有icon-
的前缀;
四、封装组件
- 我是用的是 组合式API;
- 大家如果使用的是选项式API,可以前往官网,使用这块有具体以的教程;
- vite-plugin-svg-icons官方中文文档;
4.1 封装组件
-
组件所在位置 :
src/components/SvgIcon/index.vue
;
-
封装组件 :
html<script setup lang="ts" name="SvgIcon"> // 声明props withDefaults( defineProps<{ name: string; width?: string; height?: string; }>(), { // 默认大小大家可以根据自己的需要设置 width: '1em', height: '1em' } ); </script> <template> <svg aria-hidden="true" class="svg-icon"> <use :href="`#icon-${name}`" /> </svg> </template> <style scoped lang="scss"> /* 动态设置样式 */ .svg-icon { width: v-bind(width); height: v-bind(height); } </style>
4.2 给组件添加类型
-
目标文件 :
src/types/components.d.ts
-
代码:
ts// 方式一 import SvgIcon from '@/components/SvgIcon'; // 固定写法 declare module 'vue' { interface GloablComponents { // 组件名称: typeof 组件; // typeof 操作符能得到 组件的类型再给组件 SvgIcon: typrof SvgIcon } } // 方式二 declare module 'vue' { interface GlobalComponents { SvgIcon: typeof import('@/components/SvgIcon'); } }