前端开发小技巧 - 【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');
      }
    }
相关推荐
开开心心就好5 小时前
批量提取PDF中的图片,直接导出原图
前端·javascript·支持向量机·智能手机·pdf·html·启发式算法
Setsuna_F_Seiei7 小时前
前端转型 Agent 开发 05 之 Agent Hooks 与 Checkpointer(让 Agent 从全自动转变人为可掌控)
前端·agent·ai编程
百万蹄蹄向前冲9 小时前
风扇转了一晚上MVP专家团翻车事故
前端·人工智能
默_笙9 小时前
🏛 给 AI 配一间办公室:Harness Engineering 六大模块与它的实现
前端·javascript
linux_cfan10 小时前
videojs v10 源代码系列解读:14 · 谓词守卫:在运行时安全地调用能力
前端·javascript·音视频
kyriewen10 小时前
我扒了 10,221 条 JD:腾讯技术岗 75% 在要 AI
前端·人工智能·ai编程
郑州光合科技余经理11 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
+VX:Fegn089512 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
雪芽蓝域zzs12 小时前
第 7 章:双 Y 轴组合图(柱状 + 折线,看板高频场景)
vue.js·echars
IT_陈寒12 小时前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端