如何使用Svg矢量图封装引用到vue3项目中

news2024/9/25 13:25:36

前言

在现代前端开发中,SVG(可缩放矢量图形)因其高质量和灵活性成为了图标和图形设计的热门选择。对于 Vue 3 项目而言,将 SVG 图标封装和引用到项目中不仅能提升性能,还能带来更高的可维护性和一致性。SVG 图标本质上是矢量图形,因此无论放大还是缩小,图像都不会失真,这使得它们在响应式设计中表现尤为出色。此外,通过封装 SVG 图标,可以将图标的样式和行为与组件紧密结合,简化管理和重用的过程。这种做法不仅优化了开发流程,也提升了用户体验。接下来,我们将探讨如何在 Vue 3 项目中有效地封装和引用 SVG 图标,帮助你充分发挥它们的优势。

一、如何在线使用svg图标

1、打开iconfont素材网站,集成 svg 图标

iconfont素材网站

icomoon素材网站

  • 创建 iconfont 项目
  • 找到合适的 svg 图标
  • 添加购物车到项目中

2、本地上传svg图标

  • 挑选 svg 图标下载
  • 打开iconfont上传 svg 图标
  • 上传的svg图标添加至iconfont 项目

image.png

3、symbol 引用

官方帮助文档:查看,推荐使用 symbol 方式

  • 支持多色图标了,不再受单色限制。
  • 通过一些技巧,支持像字体那样,通过font-size,color来调整样式。
  • 兼容性较差,支持 ie9+,及现代浏览器。
  • 浏览器渲染svg的性能一般,还不如png。
  1. 第一步:拷贝项目下面生成的symbol代码:

image.png

<script src="//at.alicdn.com/t/c/font_4546577_a2gvbkwn7z.js"></script>
  1. 第二步:加入通用css代码(引入一次就行:
<style type="text/css">
    .icon {
       width: 1em; height: 1em;
       vertical-align: -0.15em;
       fill: currentColor;
       overflow: hidden;
    }
</style>
  1. 第三步:挑选相应图标并获取类名,应用于页面:
<svg class="icon" aria-hidden="true">
    <use xlink:href="#icon-xxx"></use>
</svg>

4、封装 svg 组件

  1. 外部引用 symbol 链接

  2. 接收 icon name

在vue3项目public/index.html中引入symbol 链接

<script src="//at.alicdn.com/t/c/font_4546577_a2gvbkwn7z.js"></script>
  1. icon 外层样式封装

创建src/components/Icon.vue

<template>
  <div class="icon-wrapper" :style="{ ...style }">
    <svg class="icon">
      <use :href="iconName"></use>
    </svg>
  </div>
</template>

<script setup>
import { computed, defineProps } from "vue";

const props = defineProps({
  name: String,
  prefix: {
    type: String,
    default: "icon-",
  },
  style: Object,
});

const iconName = computed(() => `#${props.prefix}${props.name}`);
</script>

<style lang="scss" scoped>
.icon {
  width: 100%;
  height: 100%;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
.icon-wrapper {
  display: inline-block;
}
</style>
  1. 引用Svg组件
<template>
  <div class="wrapper">
    <i-icon name="vuejs_icon" />
  </div>
</template>

<script setup>
import IIcon from "@/components/Icon.vue";
</script>

<style lang="scss" scoped>
.wrapper {
  width: 100%;
  height: 100%;
}
</style>

image.png

二、如何直接使用外部、内部的svg图标

  • 显示外部svg图标
  • 显示内部svg图标

1、封装svg图标组件

新建src/components/SvgIcon/index.vue

<template>
  <div
    v-if="isExternal"
    :style="styleExternalIcon"
    class="svg-external-icon svg-icon"
    :class="className"
  />
  <!-- 即使 aria-hidden="true" 可以阻止内容被辅助技术读取,它并不会影响内容的视觉显示。因此,您可能需要使用CSS来隐藏这些元素(如果适用)。但是,请注意,仅仅使用CSS隐藏元素并不足以确保它们对辅助技术用户是不可见的。 -->
  <svg v-else class="svg-icon" :class="className" aria-hidden="true">
    <use :xlink:href="iconName" />
  </svg>
</template>

<script setup>
// 避免重名,将 external当做isExternal来使用
import { isExternal as external } from '@/utils/validate'
import { defineProps, computed } from 'vue'
// defineProps接受父组件传入的对象
const props = defineProps({
  // icon 图标
  icon: {
    type: String,
    required: true
  },
  // 图标类名
  className: {
    type: String,
    default: ''
  }
})

/**
 * 判断是否为外部图标
 */
const isExternal = computed(() => external(props.icon))
/**
 * 外部图标样式
 */
/**
 * mask: 是一个 CSS 属性,用于将图像用作元素的遮罩。遮罩定义了
 * 哪些部分应该显示(图像的白色或透明部分),哪些部分应该隐藏
 * (图像的黑色部分)。no-repeat 50% 50% 表示图像不会重复,并且会居中放置。
 */
const styleExternalIcon = computed(() => ({
  mask: `url(${props.icon}) no-repeat 50% 50%`,
  '-webkit-mask': `url(${props.icon}) no-repeat 50% 50%`
}))
/**
 * 项目内图标
 */
const iconName = computed(() => `#icon-${props.icon}`)
</script>

<style scoped>
.svg-icon {
  width: 100%;
  height: 100%;
  fill: currentColor;
  overflow: hidden;
}

.svg-external-icon {
  background-color: currentColor;
  mask-size: cover !important;
  display: inline-block;
}
</style>

2、判断是否为外部图标

新建src/utils/validate.js

/**
 * 判断是否为外部资源
 */
export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path)
}
/**
 * return /^(https?:|mailto:|tel:)/.test(path):这行代码是函数的
 * 主体,它返回一个布尔值。这里使用了正则表达式
 * ^(https?:|mailto:|tel:) 来检查 path 字符串是否以 http:、https:、mailto: 或 tel: 开头。
 */

3、通过组件来显示外部svg图标

新建src/

<template>
  <div class="wrapper">
    <span class="svg-container">
      <svg-icon
        icon="http://118.178.232.152:8001/#icon-vuejs_icon"
      />
    </span>
  </div>
</template>

<script setup>
import SvgIcon from "@/components/SvgIcon/index.vue";
</script>

<style lang="scss" scoped>
.wrapper {
  width: 100%;
  height: 100%;
}
.svg-container {
  vertical-align: middle;
  display: inline-block;
  width: 80px;
  height: 80px;
}
</style>

image.png

请求外部图标时可能会遇到跨域问题,所以尽量下载到本地项目中进行使用

image.png

4、内部引用svg图标

收集待使用的svg图标,下载放置项目的src/icons/svg/的文件夹中,如放入一个vuejs_icon.svg图标

5、完成导入所有的svg图标

src/icons/index.js

// 导入所有的svg图标
import SvgIcon from '@/components/SvgIcon'
// https://webpack.docschina.org/guides/dependency-management/#requirecontext
// 通过 require.context() 函数来创建自己的 context
// 给这个函数传入三个参数:要搜索的目录、是否还搜索其子目录,匹配文件的正则表达式。
const svgRequire = require.context('./svg', false, /\.svg$/)
// 此时返回一个 require 的函数,可以接受一个 request 的参数,用于 require 的导入。
// 该函数提供了三个属性,可以通过 require.keys() 获取到所有的 svg 图标
// 遍历图标,把图标作为 request 传入到 require 导入函数中,完成本地 svg 图标的导入
svgRequire.keys().forEach((svgIcon) => svgRequire(svgIcon))
// console.log(svgRequire.keys(), 'svgRequire')
// 导入所有的svg图标
// console.log(svgRequire('./user.svg'), 'svgIcon')

// 完成svgicon的全局注册
export default (app) => {
  app.component('svg-icon', SvgIcon)
}

6、全局导入SvgIcon

src/main.js

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
// 导入 svgIcon
import installIcons from "@/icons";

const app = createApp(App);
installIcons(app);
app.use(store).use(router).mount("#app");

7、通过组件来显示内部svg图标

<template>
  <div class="wrapper">
    <span class="svg-container">
      <svg-icon icon="vuejs_icon" />
    </span>
  </div>
</template>

<script setup></script>

<style lang="scss" scoped>
.wrapper {
  width: 100%;
  height: 100%;
}
.svg-container {
  vertical-align: middle;
  display: inline-block;
  width: 80px;
  height: 80px;
}
</style>

image.png

8、直接复制使用svg代码(不推荐使用)

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

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

相关文章

LED的使用寿命评估

一&#xff0e;前言 LED光源随着时间的推移&#xff0c;输出光功率会逐渐衰减。在某一时间点&#xff0c;当LED发出的光衰减到一定水平&#xff0c;就无法满足应用要求。因此&#xff0c;常遇见客户会索取产品中LED光源的使用寿命数据。那么怎样确认LED的使用寿命呢&#xff1…

视觉Mamba综述——Visual Mamba: A Survey and New Outlooks论文总结

Visual Mamba: A Survey and New Outlooks &#xff08;31页&#xff0c;视觉Mamba综述&#xff09; 香港科技大学计算机科学与工程系 https://github.com/Ruixxxx/Awesome-Vision-Mamba-Models. 任务背景 0.摘要 Mamba是最近提出的一种选择性结构化状态空间模型&#xff…

公共DNS大测评,哪个解析性能最好?

日前阿里云方面发布公告称&#xff0c;由于产品升级&#xff0c;将于2024年9月30日24时起对公共DNS中免费的解析请求采取智能流量管控措施。据其透露&#xff0c;“公共DNS仍会致力于为广大免费用户提供高质量的基础递归解析服务&#xff0c;但在高并发解析场景&#xff0c;将对…

建模杂谈系列249 增量数据的正态分布拟合

说明 从分布开始&#xff0c;分布又要从正态开始 假设有一批数据&#xff0c;只有通过在线的方式增量获得。 内容 1 生成 先通过numpy生成一堆随机数据&#xff0c;从3个正态分布生成&#xff0c;然后拼接起来。 import numpy as np import matplotlib.pyplot as plt from …

【智能算法改进】路径规划问题的多策略改进樽海鞘群算法研究

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】樽海鞘群算法&#xff08;SSA)原理及实现 2.改进点 无标度网络策略 复杂网络在图论中可以用边和节点表示&#xff0c; Barabasi 等于1999年通过分析大量的数据提出了无标度网络模型. 该网络…

框架 +【Mybatis】概述 以及 基础环境搭建

目录 什么是框架&#xff1f; java后端框架包括 Mybatis概述 1、背景介绍 2、mybatis介绍 Mybatis环境搭建 1.创建一个maven项目 2.导入mysql数据库驱动包 导入mybatis依赖的jar包 3.创建一个全局的mybatis配置文件 4.创建数据库,创建表,准备数据 5.创建一个访问接口…

单图生成 2D 和 3D 人物,高质量图像处理模型 CharacterGen来啦!

CharacterGen引入了一个简化的生成流程和一个图像条件的多视图扩散模型。该模型有效地将输入姿态校准到规范形式&#xff0c;同时保留输入图像的关键属性&#xff0c;从而解决了多样化姿态带来的挑战。 CharacterGen的另一个核心组成部分是基于Transformer的、可泛化的稀疏视图…

httpx:一个神奇的 Python HTTP客户端

文章目录 httpx&#xff1a;一个神奇的 Python HTTP客户端1. 背景&#xff1a;为什么选择 httpx&#xff1f;2. httpx 是什么&#xff1f;3. 如何安装 httpx&#xff1f;4. 简单的库函数使用方法5. 场景应用6. 常见问题及解决方案7. 总结 httpx&#xff1a;一个神奇的 Python H…

第 8 章 数据的家——MySQL的数据目录

8.1 数据库和文件系统的关系 数据库把表存储在文件系统上。当我们读取数据时&#xff0c;存储引擎会从文件系统中把数据读出来返回给我们&#xff1b;当我们写入数据时&#xff0c;存储引擎会把这些数据写回文件系统。 8.2 MySQL数据目录 8.2.1 数据目录和安装目录的区别 数…

C++从入门到起飞之——list模拟实现 全方位剖析!

​ ​ ​ &#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 ​ ​1、list的整体框架 2、list迭代器 >整体分析 >整体框架 >成员函数 >运…

操作系统:实验六文件操作实验

一、实验目的 1、了解文件系统功能及实现原理。 2、掌握LINUX下文件操作的有关系统调用。 3、熟悉main函数带参数运行的有关操作过程。 4、通过模拟程序实现简单的一级文件系统或二级文件系统。 二、实验内容 1、编程显示文件自身。&#xff08;1分&#xff09; #includ…

分享两个方法分析python打包exe

在Python开发中&#xff0c;常常需要将Python脚本打包成独立的可执行文件&#xff0c;以便在没有Python环境的电脑上运行。你是否曾为此感到困惑&#xff0c;不知道该选择哪种工具来实现这一目标&#xff1f;其实&#xff0c;打包Python脚本并不难&#xff0c;关键在于选择合适…

Mybatis框架——缓存(一级缓存,二级缓存)

本章将简单介绍Mybatis框架中的缓存&#xff0c;欢迎大家点赞➕收藏&#xff0c;蟹蟹&#xff01;&#xff01;&#xff01;&#x1f495; &#x1f308;个人主页&#xff1a;404_NOT_FOUND &#x1f308;MyBatis环境搭建步骤&#xff08;超全解析&#xff01;&#xff01;&am…

AI写论文真的可靠吗?免费推荐6款AI论文写作助手

在当今的学术研究和写作领域&#xff0c;AI论文写作助手已经成为不可或缺的工具。这些工具不仅能够提高写作效率&#xff0c;还能帮助研究者生成高质量的论文。以下是六款免费推荐的AI论文写作助手&#xff0c;包括千笔-aipasspaper&#xff0c;它们各自具有独特的功能和优势。…

【hot100篇-python刷题记录】【最小路径和】

R6-多维动态规划篇 好经典的dp题&#xff0c;纯粹的题。 多维动态规划无论是二维还是三维&#xff0c;无非是创建dp表&#xff0c;dp[][][][][][]即可 动态规划式子 dp[i][j]当前值min(dp[i][j-1],dp[i-1][j]) 边界问题处理&#xff1a;是否存在即可。哦对了好像不用这样&a…

探索异步之美:aiohttp库的魔力与奥秘

文章目录 探索异步之美&#xff1a;aiohttp库的魔力与奥秘背景&#xff1a;为何选择aiohttp&#xff1f;什么是aiohttp&#xff1f;如何安装aiohttp&#xff1f;简单函数使用方法场景应用常见Bug及解决方案总结 探索异步之美&#xff1a;aiohttp库的魔力与奥秘 背景&#xff1…

Linux教程七:文件目录类命令ls、cd(图文详解)

默认登录出现一个[用户localhost ~] 代表时登陆用户的家目录 1、 Linux ls命令 基本用法 ls&#xff1a;列出当前目录下的文件和目录&#xff08;不包括以.开头的隐藏文件&#xff09;。ls 目录名&#xff1a;列出指定目录下的文件和目录。 常用选项 -l&#xff1a;以长格式列出…

【Python 报错已解决】`TypeError: ‘method‘ object is not subscriptable`

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引言 在编程的世界里&#xff0c;我们经常会遇到各种报错&#xff0c;它们像隐藏在代码中的小怪兽&#xff0c;时不时跳出来给…

Java项目:基于SpringBoot+mysql在线拍卖系统(含源码+数据库+答辩PPT+毕业论文)

一、项目简介 本项目是一套基于SSM框架mysql在线拍卖系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能齐全、…

常见的性能测试方法!

前言 性能测试划分有很多种&#xff0c;测试方法也有很多种&#xff0c;更确切的说是由于测试方法的不同决定了测试划分的情况&#xff0c;但在测试过程中性能测试的划分没有绝对的界限&#xff0c;常用的有压力测试、负载测试和并发用户测试等。 性能测试的方法主要包括以下…