vue3+vite:封装Svg组件

news2024/11/24 20:24:48

前言

在项目开发过程中,以svg图片引入时,会遇到当hover态时图片颜色修改的场景,我们可能需要去引入另一张不同颜色的svg图片,或者用css方式修改,为了方便这种情况,需要封装svg组件来自定义宽高和颜色,优化使用。

1. 什么是SVG

SVG (Scalable Vector Graphics) 是一种基于 XML 的矢量图形格式,用于描述二维图形和图像。与传统的栅格图像(如 JPEG、PNG)不同,SVG 使用数学公式来定义图形,因此可以无损地进行缩放和放大,并保持图像的清晰度和质量。
以下是一些关于 SVG 的特点和用途:

  • 矢量图形:SVG 使用几何形状、路径和文本对象来描述图形。这些对象可以通过调整大小、平移和变换等操作进行精确控制,而不会像栅格图像一样失真。
  • 可伸缩性:SVG 图形可以根据需要进行任意大小的缩放,而不会损失图像的清晰度。这使得 SVG 在不同的设备分辨率和屏幕尺寸下都能保持良好的呈现效果。
  • 文本支持:除了图形,SVG 还支持添加文本元素,可以在图形中嵌入文本内容,比如标题、标签、图例等。
  • 动画和交互性:SVG 支持通过 CSS、JavaScript 或 SMIL(Synchronized Multimedia Integration Language)实现动画效果和交互特性。可以使用这些技术为 SVG 图形添加动态效果、响应用户操作和实现无缝的用户体验。
  • Web 标准:SVG 是 Web 标准之一,被广泛支持和应用于各种 Web 技术中,包括网页设计、图标制作、数据可视化和交互式图形。

SVG 图像可以在各种图像编辑器(如 Adobe Illustrator、Inkscape)中创建和编辑,并嵌入到 HTML 文件中进行展示。通过 CSS 和 JavaScript,SVG 图像可以与网页的其他元素和样式进行集成和调整。

2. 封装Svg组件

2.1 方式一:vite-plugin-svg-icons

vite-plugin-svg-icons 是一个 Vite 插件,用于在 Vite 2 项目中方便地使用 SVG 图标。它可以自动将 SVG 图标文件转换为 Vue 组件,并且提供了一些配置选项来自定义生成的组件。
具体来说,vite-plugin-svg-icons 提供了以下功能:

  • 自动转换:当你将 SVG 文件放置在指定目录下时,插件会自动将它们转换为可用的 Vue 组件。你无需手动处理 SVG 文件转换的步骤,这样可以节省开发时间。
  • 自动导入:一旦 SVG 文件被转换为 Vue 组件,它们会被自动导入到你的项目中。你只需要在代码中使用这些组件即可,无需手动导入每个 SVG 文件。
  • 优化输出:插件会对 SVG 图标进行优化,包括移除冗余信息、压缩文件大小等。这样可以减少加载时间,并改善性能。
    vite-plugin-svg-icons官网
    使用步骤:
  1. 安装 vite-plugin-svg-icons:
npm install vite-plugin-svg-icons -D
  1. 在 vite 配置文件中添加插件
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import path from "path";
export default defineConfig({
  plugins: [
    vue(),
    createSvgIconsPlugin({
      // 指定目录(svg存放目录)
      iconDirs: [path.resolve(process.cwd(), "src/assets/svgs")],
      // 使用 svg 图标的格式(name为图片名称)
      symbolId: "icon-[name]",
      //生成组件插入位置 只有两个值 boby-last | body-first
      inject: 'body-last'
    })
  ],
})
  1. 在main.ts文件中全局导入
import 'virtual:svg-icons-register';
  1. 封装svg组件
    封装svg组件,可修改宽高和颜色
<template>
  <svg
      aria-hidden="true"
      :width="width"
      :height="height"
      :fill="color"
  >
      <use :xlink:href="`#icon-${name}`"/>
  </svg>
</template>
<script setup lang="ts">
  defineProps<{
    name: string,
    width: string,
    height: string,
    color?: string
  }>();
</script>
  1. 使用
<template>
  <SvgIcon name="close" width="24" height="24"></SvgIcon>
  </template>
  <script setup>
  import SvgIcon from "@/components/svg-icon/svg-icon.vue";
</script>

问题:
● vite-plugin-svg-icons插件自动封装的组件只能选择插入到body前或后
在这里插入图片描述
如果项目中某个部分使用了shadow-dom,由于样式隔离的问题,使用svg组件不显示
解决:通过id(如上图为__svg__icons__dom)获取插件自动封装的组件dom元素,插入到shodaw-dom下即可解决

● 原本svg图片的宽高失效,需要重新设置宽高,而且不能直接改变颜色,想要改变颜色必须修改原svg图片,将其fill属性删掉或者置为空(“”)

2.2 方式二:通过css属性

CSS 中的 mask 属性用于创建遮罩效果,它可以通过另一个图像或者 SVG 图像来定义遮罩的形状。mask 属性可以应用于任何可视元素,并将遮罩应用于元素的内容和背景。
mask属性详情

<template>
  <div
      class="bot-svg-icon"
      :style="svgStyle"
  ></div>
</template>
<script setup lang="ts">
import {computed, ref} from 'vue';
const props = withDefaults(defineProps<{
    url: string,
    width: string|number,
    height: string|number,
    color?: string,
}>(), {
    color: 'var(--bot-color-black-1)',
});
const svgStyle = computed(() => ({
    width: props.width + 'px',
    height: props.height + 'px',
    backgroundColor: props.color
    maskImage: `url(${props.url})`,
}));

</script>

<style scoped>
.bot-svg-icon {
    display: inline-block;
    mask-repeat: no-repeat;
    mask-size: cover;
}
</style>

问题:原本的svg图片宽高失效,需要重新设置宽高,但是可以不用修改原svg文件就可改变颜色。

3. 其他问题

动态导入地址导致的问题:在本地图片显示正常,打包后部署,图片不能显示,如下例:

//第一种情况:在html中时候,本地运行和打包后线上运行都ok。
<img src="@/assets/close.svg" alt="" >

//第二种情况:用动态数据,本地运行ok,打包后线上运行不显示
const path = "@/assets/close.svg";
// 如果是vue3+webpack可以使用require引入,但vite没有require
<img :src="path">

// 第三种情况:用动态数据且本地和线上访问都可显示
const path = new URL("@/assets/close.svg", import.meta.url).href;
<img :src="path">

// 第四种情况:用动态数据且本地和线上访问都可显示
import close from "@/assets/close.svg";
<img :src="close">

参考vite官方文档:静态资源处理

参考文章:
https://juejin.cn/post/7261914349726597181

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1400515.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IaC基础设施即代码:Terraform 进行 lifecycle 生命周期管理

目录 一、实验 1.环境 2.Terraform 创建网络资源 3.Terraform 进行 create_before_destroy&#xff08;销毁前创建新资源&#xff09; 4.Terraform 进行 prevent_destroy&#xff08;防止资源被销毁&#xff09; 5.Terraform 进行 ignore_changes&#xff08;忽略资源的差…

记录汇川:H5U与Factory IO测试15

主程序&#xff1a; 子程序&#xff1a; IO映射 子程序&#xff1a; 出料程序 子程序&#xff1a; 视觉判断 子程序&#xff1a; 自动程序 Factory IO配置&#xff1a; 实际动作如下&#xff1a; Factory IO测试15

【本科生机器学习】【北京航空航天大学】课题报告:支持向量机(Support Vector Machine, SVM)初步研究【上、原理部分】

说明&#xff1a; &#xff08;1&#xff09;、仅供个人学习使用&#xff1b; &#xff08;2&#xff09;、本科生学术水平有限&#xff0c;故不能保证全无科学性错误&#xff0c;本文仅作为该领域的学习参考。 一、课程总结 1、机器学习&#xff08;Machine Learning, ML&am…

【Docker】安装 Nacos容器并根据Nginx实现负载均衡

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Docker实战》。&#x1f3af;&#x1f3af; &…

Go使用记忆化搜索的套路【以20240121力扣每日一题为例】

题目 分析 这道题很明显记忆化搜索&#xff0c;用py很容易写出来 Python class Solution:def splitArray(self, nums: List[int], k: int) -> int:n len(nums)# 寻找分割子数组中和的最小的最大值s [0]for num in nums:s.append(s[-1] num)#print(s)cachedef dfs(cur,…

跟着pink老师前端入门教程-day07

去掉li前面的项目符号&#xff08;小圆点&#xff09; 语法&#xff1a;list-style: none; 十五、圆角边框 在CSS3中&#xff0c;新增了圆角边框样式&#xff0c;这样盒子就可以变成圆角 border-radius属性用于设置元素的外边框圆角 语法&#xff1a;border-radius:length…

1.11马原

同一性是事物存在和发展的前提&#xff0c;一方的发展以另一方的发展为条件 同一性使矛盾双方相互吸收有利于自身的因素&#xff0c;在相互作用中各自得到发展 是事物发展根本规律&#xff0c;唯物辩证法的实质和核心 揭示了事物普遍联系的根本内容和变化发展的内在动力 是贯…

Vue3 在 history 模式下通过 vite 打包部署白屏

Vue3 在 history 模式下通过 vite 打包部署后白屏; 起因 hash 模式 url 后面跟个 # 强迫症犯了改成了 history,就此一波拉锯战开始了 ... 期间 nigix 和 router 各种反复排查尝试最终一波三折后可算是成功了 ... Vue官方文档 具体配置可供参考如下: 先简要介绍下,当前项目打包…

SpringBoot整合Dubbo和Zookeeper分布式服务框架使用的入门项目实例

文章目录 SpringBoot整合Dubbo和Zookeeper分布式服务框架使用的入门项目实例Dubbo定义其核心部分包含: 工作原理为什么要用dubbo各个节点角色说明&#xff1a;调用关系说明&#xff1a; dubbo为什么需要和zookeeper结合使用&#xff0c;zookeeper在dubbo体系中起到什么作用&…

0基础开发EtherNet/IP:协议格式,JAVA、C#、C++处理

经过一阵倒腾&#xff0c;把CIP、Ethernet/ip协议搞到手 协议的概念和理论就不提及了&#xff0c;上网随便一搜索EtherNet/IP遍地都是。 直接将协议关键点列举出来吧。 更多协议资料 www.jngbus.com 通讯软件群 30806722 这里讲解的是TCP和UDP协议的格式&#xff0c;EtherN…

【标准IO】fseek函数、ftell函数、fflush函数、getline函数

目录 fseekftellrewindfflushgetline 橙色 当你在文件中写入了10个字符后&#xff0c;又想把这10个字符读出来&#xff0c;该怎么做呢&#xff1f;因为有文件操作符指针的存在&#xff0c;此时该指针已经指在了这10个字符末尾&#xff0c;所以需要把该指针重定向&#xff0c;这…

RT-Thread Studio学习(十七)虚拟串口

RT-Thread Studio学习&#xff08;十七&#xff09;虚拟串口 一、简介二、新建RT-Thread项目并使用外部时钟三、启用USB设备功能四、测试 一、简介 本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下实现USB虚拟串口。 硬件及开发环境如下&#xff1a; OS WI…

油管公式(全)

原文&#xff1a;The Youtube Formula 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 每个人都应该有一个 YouTube 频道。真的每个人&#xff0c;尤其是品牌。当我看到没有在 YouTube 上存在的品牌时&#xff0c;我觉得他们疯了。任何人都不利用这个机会是难以想…

python-基础篇-变量

文章目录 变量的基本使用目标01. 变量定义1) 变量演练1 —— iPython2) 变量演练 2 —— PyCharm3) 变量演练 3 —— 超市买苹果思考题 02. 变量的类型2.1 变量类型的演练 —— 个人信息2.2 变量的类型2.3 不同类型变量之间的计算1) **数字型变量** 之间可以直接计算2) **字符串…

从零开始:直播电商APP开发全流程解析

本篇文章&#xff0c;小编将从零开始&#xff0c;全面解析直播电商APP的开发流程&#xff0c;涵盖了关键的技术要点和开发阶段的关键步骤。 第一阶段&#xff1a;需求分析与规划 此阶段的关键任务包括&#xff1a; 1.用户需求调研 2.功能规划 3.技术选型 第二阶段&#xf…

安卓平板局域网内远程控制工控机方法

安卓平板局域网内远程控制工控机方法 将所需要远程控制的工控机通过网线连接到具有WiFi功能的路由器上&#xff0c;将安卓平板连接上WiFi&#xff0c;如下图所示 下载NoMachine远程软件安装包&#xff0c;官网地址&#xff1a;https://www.nomachine.com/ 点击Download now按钮…

图论:最短路(dijkstra算法、bellman算法、spfa算法、floyd算法)详细版

终于是学完了&#xff0c;这个最短路我学了好几天&#xff0c;当然也学了别的算法啦&#xff0c;也是非常的累啊。 话不多说下面看看最短路问题吧。 最短路问题是有向图&#xff0c;要求的是图中一个点到起点的距离&#xff0c;其中我们要输入点和点之间的距离&#xff0c;来求…

【Docker】安装Nginx容器并部署前后端分离项目

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Docker实战》。&#x1f3af;&#x1f3af; &…

代码随想录算法训练营第十一天|● 20. 有效的括号 ● 1047. 删除字符串中的所有相邻重复项 ● 150. 逆波兰表达式求值

文章目录 20.有效的括号思路&#xff1a;代码&#xff1a; 1047. 删除字符串中的所有相邻重复项思路代码1:栈储存代码2&#xff1a;双指针 150. 逆波兰表达式求值思路&#xff1a;题外话代码 20.有效的括号 思路&#xff1a; 由于栈结构的特殊性&#xff0c;非常适合做对称匹配…

单体架构、微服务和无服务器架构

前言 在这篇文章中&#xff0c;我将演示在决定使用单体架构、微服务架构和无服务器架构时的权衡的简化心智模型。目标是突显每种风格的固有优势和缺陷&#xff0c;并提供关于何时选择哪种架构风格的指导。 单体架构 对于小团队或项目来说是理想的入门架构。它简单易上手&…