封装svg图标组件

简介: 封装svg图标组件

前言🌴🌴


在项目开发的过程中,我们会使用到大量的SVG图标,那么如果我们在项目中直接进行引用这样就太不方便,今天就来讲一下如何封装一个支持本地 SVG 图标和在线 SVG 图标的组件 svg-icon


什么是SVG图标?🥝🥝


简介:SVG是一种可伸缩的矢量图型(就是用标签代码来画图),它基于XML并用于描述图形的语言;如果我们通过vscode打开SVG图片,会发现他是基于一大串代码实现的。这和其他图片是以像素来描绘的不一样。

  • 不同于用像素来描绘的矩阵图像(JPG、PNG、GIF),SVG是和分辨率无关,也就是说,他和其他图片不同的地方就在于他放大也不会失真,图片依旧保持清晰。;
  • SVG图像可以通过JS和DOM操作来创建和操控;
  • SVG有自己庞大的语法和较大的复杂度,我们这里只是了解下有这种图像格式;


在本地引入一些svg图标 🍂🍂


介绍一下require.context


在接下来的工作开始之前,首先要介绍一下要使用到的API:

require.context方法进行简介:

他其实是一个webpack的API,获取一个特定的上下文,主要用来实现自动化导入模块。

使用场景:如果遇到从一个文件夹引入很多模块的情况,可以使用这个API,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块

接收三个参数:require.context(directory,useSubdirectories,regExp)

  • directory这个参数表明要检索的目录
  • useSubdirectories传入一个布尔值,表明是否检索子文件
  • regExp匹配的正则表达式,一般是文件名

值得注意的是require.context函数执行后返回的是一个函数,并且这个函数有3个属性,我们重点了解其中的一个

  • keys {Function} -返回匹配成功模块的名字组成的数组


开始配置


首先在src下面创建icons文件夹,在src/icons里面创建svg文件夹,在svg文件夹中引入svg图片,

同时在svg文件夹的平级创建index.js文件

然后在index.js文件中进行一些配置:

  • 首先引入SvgIcon这个组件
  • 然后使用require.context函数,返回一个函数,定义为svgRequire
  • 然后通过遍历svgRequire.keys()来获取匹配的svg路径
  • 注意返回的svgRequire函数接收一个参数,用于指定要导入的文件路径。通过在循环中调用svgRequire(svgIcon),我们将每个图标文件路径作为参数传递给这个导入函数,以完成对每个图标文件的导入操作。
  • 具体来说,这些导入的图标文件将被 webpack 处理,并根据配置将它们打包到最终生成的 JavaScript bundle 中。
  • 当你在应用程序的其他组件中使用 <svg-icon> 组件时,实际上是在使用已导入到 JavaScript bundle 中的 SVG 图标模块。这些图标模块可以根据需要在运行时动态加载和渲染。
  • 因此我们还需要进行一些webpack的配置
import SvgIcon from '@/components/SvgIcon';
// 使用这个api来完成导入
// https://webpack.docschina.org/guides/dependency-management/#requirecontext
const svgRequire = require.context('./svg', false, /.svg$/);
svgRequire.keys().forEach((svgIcon) => {
  svgRequire(svgIcon);
});
// 完成全局注册,这里传入的是main.js中创建的app实例
export default (app) => {
  app.component('svg-icon', SvgIcon);
};


如何封装svg组件 🐤🐤


首先我们需要在scr/component下面创建一个SvgIcon文件夹,并在里面创建一个index.vue文件

接下来我们要在创建的文件中写入下面的代码。


定义props部分


首先定义props,这里面我选择的是Vue3的setup语法糖的书写形式,这个props接收两个参数,一个icon就是要接受的icon图标的名字,当然,这个图标名称还要后续的进一步加工,也就是说,iconName是真正的名称,之所以要这么做是因为等一会需要进行配置项处理。另一个className是传递过来的icon的类名。

const props = defineProps({
  icon: {
    type: String,
    required: true
  },
  // 图标类名
  className: {
    type: String,
    default: ''
  }
});
// 项目内部图标,就相当于是一个名称
const iconName = computed(() => `#icon-${props.icon}`);

因为我们这个组件不仅要实现能够内部引用SVG图标还要能够引用外部的SVG图标(比如阿里的图标库),所以我们要进行一个判断该图标是否为外部引用的。

const isExternal = computed(() => external(props.icon));
-------------------------------
// 判断是否是外部图标
export function isExternal(path) {
  // 判断是否是这几个开头,如果是的话那么就是外部图标
  return /^(https?:|http)/.test(path);
}

这里面我进行了一个简单的判断,如果是以http或者https开头的,那么就认为这个SVG图标是从网站引用的,是一个在线的SVG图标。


HTML部分


下面这部分是进行简单的HTML处理,如果是外链的SVG图标就显示第一个,如果是项目内部的图标那就显示下面的

<template>
  <!-- 判断是否为外部图标 -->
  <div
    v-if="isExternal"
    :style="styleIsExternalIcon"
    class="svg-icon svg-external-icon"
    :class="className"
  ></div>
  <!-- 内部图标 -->
  <svg v-else class="svg-icon" :class="className" aria-hidden="true">
    <use :xlink:href="iconName"></use>
  </svg>
</template>

在这里使用了HTML中的svg标签,首先我们要先介绍一下svg标签:

  • SVG 代码以<svg> 元素开始,包括开启标签 <svg> 和关闭标签 </svg>
  • width 和 height 属性可设置此 SVG 文档的宽度和高度
  • version 属性可定义所使用的 SVG 版本,xmlns 属性可定义 SVG 命名空间。

那么这里的use又是什么呢?

  • 标记的作用是能从SVG文档内部取出一个节点,克隆它,并把它输出到别处。跟‘引用’很相似,但它是深度克隆
  • 比如你在同一个svg中定义了一个矩形元素:
<rect id="myRect" width="100" height="50" />

然后你想要在进行复用,那么你就可以使用use标签:

<use xlink:href="#myRect" />

这里面的xlink:href属性后面引用的图形元素的唯一标识符(通常是该元素的id属性的值)


简单的样式处理


// 外部图标的样式
const styleIsExternalIcon = computed(() => ({
  mask: `url(${props.icon}) no-repeat 50% 50%`,
  '-webkit-mask': `url(${props.icon}) no-repeat 50% 50%`
}));


引入插件并进行配置项处理🚴‍♀🚴‍♀


在进行完上面的处理之后,我们发现还是无法正常的显示svg图标,这是为什么呢?

我们还需要安装一个插件

npm i --save svg-sprite-loader
  1. SVG雪碧图生成:它将多个独立的SVG文件合并为一个SVG雪碧图,即将每个SVG图标放在一个共享的SVG容器中,从而减少HTTP请求的数量。这种合并使得加载和渲染多个SVG图标变得更加高效。
  2. 自动生成模块:插件会为每个SVG图标生成一个模块,并导出一个包含图标的使用代码。这样,可以像导入其他模块一样导入这些SVG图标模块,并直接在应用中使用它们。这简化了SVG图标的使用和管理。
  3. 图标的使用:在应用程序中,您可以通过使用导入的SVG图标模块的默认导出来使用图标。这样,您可以直接在HTML、CSS或JavaScript中引用图标,而无需将每个图标作为单独的文件引入

可以打开官网进行参考

VueCli官网的配置

module.exports = defineConfig({
chainWebpack(config) {
    config.module
      // 规则
      .rule('svg')
      .exclude.add(resolve('src/icons')).end();
    config.module
      // 规则
      .rule('icons')
      // 正则,解析 .svg格式文件
      .test(/.svg$/)
      // 解析的文件
      .include.add(resolve('src/icons')).end()
      // 新增了一个解析的loader
      .use('svg-sprite-loader')
      //具体的loader
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end();
  }
})

注意这个options中的symbolId,这一部分就是我们对svg图标的名称定义,这也是svg-sprite-loader这个插件所需要的,使用"icon-[name]",其中的name就是具体的svg图标名称。

我们在vue.config中进行配置,通过使用webpack中的exclude和include来指定要处理的路径,同时我们添加了一些处理规则,使用了正则表达式来解析指定的文件。


进行使用


<span class="svg-container">
    <svg-icon icon="user" />
</span>

image.png这样就完成了本地svg图片的导入


总结😄😄


这次学习了如何对项目中的SVG图标进行一个组件封装,掌握了许多之前没有学习到的知识,感觉收获满满

相关文章
|
6月前
|
存储 JavaScript 定位技术
uinapp社交应用方案/文字聊天到音视频通话,再到同城交友匹配的核心社交功能
本系统采用前后端分离架构,UniApp开发跨平台客户端,集成uView UI与腾讯/高德地图SDK,通过Vuex管理状态,UniPush实现消息推送。业务服务器处理核心逻辑,IM系统负责实时信令传输,声网Agora实现音视频通话,通过唯一channelName联动IM与RTC,确保低延迟、高并发的稳定通信,构建高效社交应用。
670 0
uinapp社交应用方案/文字聊天到音视频通话,再到同城交友匹配的核心社交功能
|
SQL 关系型数据库 MySQL
docker上定期备份mysql数据库
本文是博主学习docker的记录,希望对大家有所帮助。
1959 0
|
2月前
|
Unix API PHP
汇率转换-汇率换算-汇率查询-外汇查询API接口介绍
本API提供实时汇率换算与查询服务,支持全球100+货币,数据每分钟更新。可精准转换金额、查询单币种对多币种汇率,广泛适用于跨境支付、外贸结算、旅游换汇等场景,响应快、覆盖全、集成便捷。
735 2
|
机器学习/深度学习 人工智能 计算机视觉
AI图像质感还原堪比专业摄影!Miracle F1:美图WHEE全新AI图像生成模型,支持超写实与多风格生成
美图WHEE推出的Miracle F1采用扩散模型技术,通过精准语义理解和多风格生成能力,可产出具有真实光影质感的专业级图像作品。
604 5
AI图像质感还原堪比专业摄影!Miracle F1:美图WHEE全新AI图像生成模型,支持超写实与多风格生成
|
人工智能 并行计算 测试技术
从商业海报到二次元插画多风格通吃!HiDream-I1:智象未来开源文生图模型,17亿参数秒出艺术大作
HiDream-I1是智象未来团队推出的开源图像生成模型,采用扩散模型技术和混合专家架构,在图像质量、提示词遵循能力等方面表现优异,支持多种风格生成。
1188 2
从商业海报到二次元插画多风格通吃!HiDream-I1:智象未来开源文生图模型,17亿参数秒出艺术大作
|
9月前
|
弹性计算 人工智能 边缘计算
阿里云国际站2025年最新动态:全球云计算加速,中小企业出海利器
2025年,阿里云国际站凭借领先技术与本地化服务,助力企业高效出海。核心产品如弹性计算ECS Enterprise、云原生数据库PolarDB-X及边缘计算ENS Pro全面升级,覆盖全球28个区域,提供低延迟、高稳定性支持。同时推出“海外现货”模式,缩短外贸订单周期50%。通过技术+生态优势,助力中小企业实现全球化增长。
|
存储 数据安全/隐私保护
基于51单片机的6位密码锁设计
该文档描述了一个基于AT89C52单片机的多功能电子密码锁系统设计,具备6位密码设置与修改功能,输入错误三次会锁定,并在LCD屏上以*号隐藏真实密码。系统包括矩阵键盘、LCD显示、AT24C02存储及报警系统,当密码错误时,会有蜂鸣器报警和LED灯闪烁。此外,还提供了密码重置(通过管理员密码131420)和输入错误提示。文中附有Proteus仿真及原理图,展示了开锁、重设密码和错误输入时的响应。
651 0
|
人工智能 数据安全/隐私保护 图形学
关于AI绘画优雅草央千澈整理的一份咒语(与AI对话提示词-应用于AI绘图和AI生成视频)-本文长期更新-本次更新2025年1月15日更新-长期更新建议点赞收藏
关于AI绘画优雅草央千澈整理的一份咒语(与AI对话提示词-应用于AI绘图和AI生成视频)-本文长期更新-本次更新2025年1月15日更新-长期更新建议点赞收藏
1127 4
|
存储 运维 前端开发
同城圈子搭子交友论坛系统/搭建圈子系统的常见问题
需求分析不明确 在系统设计初期,如果未能充分理解目标用户的需求,可能导致系统功能与实际需求脱节,进而影响用户体验。 解决方案:通过市场调研、用户访谈、问卷调查等方式深入了解用户需求,确保系统设计符合用户期望。 技术选型困难 选择合适的技术栈对于系统的稳定性和可扩展性至关重要。技术选型不当可能导致系统性能低下或开发周期延长。 解决方案:根据系统需求、开发团队的技术栈以及未来扩展性等因素综合考虑,选择适合的技术栈。例如,前端可以使用uinapp 等框架,后端可以选择PHP框架,数据库可以选择MySQL等。
550 0