前端开发小技巧 - 【TS + Vue】 - 将 svg格式 的 图片 打包成 svg地图

前言

  • 如果在一个项目中有很多png、jpg等等格式的图片,我们一般会将这些零散的图片合成一张 精灵图 ,通过背景图片的定位去使用不同的图片;
  • 如果一个项目使用到的图标绝大部分是svg格式的,为了简化使用,我们应该怎么办呢?
    • 下面就来说道说道;

一、svg简介

  • 什么是SVG
    • SVG 指可伸缩矢量图形(Scalable Vector Graphics);
    • SVG 用来定义网络的基于矢量的图形;
    • SVG 使用 XML 格式定义图形;
    • SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失;
    • SVG 是万维网联盟的标准;
    • SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体;
  • SVG2003年1月14日 成为 W3C 推荐标准;
  • svg格式的图片:
    • 它是 xml格式的;
  • 如果一个项目中有很多的svg格式的图片,我们可以打包成 svg地图 对不同的svg格式的图片进行使用;

二、打包成svg地图

  • 简单来说,svg地图 就是另一种形式的 精灵图

  • svg格式的图片打包成 svg地图 需要使用到 vite-plugin-svg-icons 这个插件;

  • 下载

    • pnpm add vite-plugin-svg-icons -D
  • 配置

    • vite-plugin-svg-icons官方中文文档;

    • 目标文件:

      • 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属性;

  • 使用步骤

    1. 在需要使用svg图片的地方,先添加一个 svg标签
    2. svg标签 内部再使用 use标签;
    3. 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-的前缀;

四、封装组件

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');
      }
    }
相关推荐
毕设十刻13 小时前
基于Vue的鲜花销售系统33n62(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
IT_陈寒14 小时前
Spring Boot 3.2震撼发布:5个必知的新特性让你开发效率提升50%
前端·人工智能·后端
初遇你时动了情14 小时前
前端使用TensorFlow.js reactjs调用本地模型 实现图像、文本、音频/声音、视频相关识别
前端·javascript·tensorflow
广州华水科技14 小时前
单北斗GNSS变形监测系统安装与应用解析,提升位移监测精度
前端
J***Q29214 小时前
前端微前端框架原理,qiankun源码分析
前端·前端框架
菜鸟‍14 小时前
【前端学习】React学习【万字总结】
前端·学习·react.js
百***844514 小时前
Webpack、Vite区别知多少?
前端·webpack·node.js
Mintopia14 小时前
零信任架构下的 WebAIGC 服务安全技术升级方向
前端·人工智能·trae
敏姐的后花园16 小时前
模考倒计时网页版
java·服务器·前端
AiXed17 小时前
PC微信WDA算法
前端·javascript·macos