vue3图标终极方案【npm包推荐】vue3-icon-sui(含源码详解)

简介

为彻底实现 vue3 项目图标自由,特开发此 npm包 vue3-icon-sui,全品类图标,通通支持!

  • iconify 图标
  • svg 图标
  • font-class 图标

安装

npm i vue3-icon-sui -S

使用

按需导入

任意页面中

import myIcon from "vue3-icon-sui";

myIcon 可为任意自定义的组件名称

全局注册

src/main.ts

import myIcon from "vue3-icon-sui";const app = createApp(App);
app.component("myIcon", myIcon);

iconify 图标

  • 必要传参 icon – iconify 官网图标的名称,支持翻转 flip
    • 水平翻转 “horizontal”
    • 垂直翻转 “vertical”
    • 水平垂直翻转 “horizontal vertical”
  1. 在 iconify 官网搜索想要的图标
    https://icon-sets.iconify.design/?query=home

在这里插入图片描述
2. 页面中使用
传给属性 icon

<myIcon icon="ic:baseline-home" color="red" size="36" />

在这里插入图片描述

svg 图标(支持多彩)

  • 必要传参 name – 项目的 src/assets/icons/svg 目录中svg 图标的名称
  1. 从https://www.iconfont.cn/ 中找到喜欢的图标
    在这里插入图片描述
    鼠标悬浮其上时,点击下载

    在这里插入图片描述
    在这里插入图片描述

    可直接下载svg,将其放入项目的 src/assets/icons/svg 目录中,改名为 nice.svg

    也可以复制 svg 代码,新建 src/assets/icons/svg/nice.svg 文件,再将 svg 代码粘贴到 nice.svg 中

  2. 页面中使用
    将 svg 图标的名称传给属性 name

    <myIcon name="nice" size="36" />
    

    效果如下
    在这里插入图片描述
    传入 color 可自定义颜色,但会丧失多彩

    <myIcon name="nice" size="36" color="red" />
    

    在这里插入图片描述

font-class 图标

  1. 从https://www.iconfont.cn/ 中找到喜欢的图标
    在这里插入图片描述

鼠标悬浮其上时,点击添加入库
在这里插入图片描述

在这里插入图片描述

加入已有项目,或新建项目

在这里插入图片描述
在这里插入图片描述
得到 url

//at.alicdn.com/t/c/font_2261937_vumtsyzbq7d.css

鼠标悬浮在项目的图标上,可一键复制代码,得到 type

icon-nice

在这里插入图片描述

  1. 页面中使用
    必传参数 url 和 type

      <myIconurl="//at.alicdn.com/t/c/font_2261937_vumtsyzbq7d.css"type="icon-nice"size="36"color="red"/>
    

    在这里插入图片描述

属性

属性名属性值说明
iconiconify 官网图标的名称,如 “ic:baseline-home”iconify图标必传
flip水平翻转 “horizontal”
垂直翻转 “vertical”
水平垂直翻转 “horizontal vertical”
仅iconify图标支持
name项目的 src/assets/icons/svg 目录中svg 图标的名称svg图标必传
rotate旋转度数,数值即可,如 90 即顺时针旋转90度所有图标都支持
color颜色,如 red所有图标都支持,但svg的多彩图标会变为纯色
size大小,数值,如 36 即 36px所有图标都支持
urlfont-class图标的css地址,详见使用范例font-class图标必传
typefont-class图标的代码,详见使用范例font-class图标必传
fontFamilyfont-class图标的前缀除非在项目设置中进行了修改,否则使用默认的 icon-font 即可

font-class 图标自定义fontFamily

在这里插入图片描述

在这里插入图片描述
通常不建议修改!

假设修改为 myfont ,则页面使用时,fontFamily属性需传入 myfont

  <myIconurl="//at.alicdn.com/t/c/font_2261937_vumtsyzbq7d.css"type="icon-nice"fontFamily="myfont"/>

源码

详解见源码注释

<script setup lang="ts">
// 优先推荐【iconify图标】必要传参 icon ,支持翻转 flip
// 搜索图标 https://icon-sets.iconify.design/// 【svg图标-支持多彩图标】必要传参 name
// 需将svg图标放在 src/assets/icons/svg 目录中,// 【font图标-不支持多彩图标】必要传参 url 和 type
// 整个项目使用多个图标时,只需有一个图标传入 url 即可import { computed, onBeforeMount, ref, watch, onMounted } from "vue";
import { Icon } from "@iconify/vue";// 接收的属性
const props = defineProps({icon: {type: String,},// 水平翻转 "horizontal"// 垂直翻转 "vertical"// 水平垂直翻转 "horizontal vertical"flip: {type: String,},name: {type: String,},// 旋转角度rotate: {type: Number,},// 图标颜色color: {type: String,},// 图标大小size: {type: [Number, String],default: 16,},url: {type: String,default: "//at.alicdn.com/t/c/font_2261937_dg35xe8b86.css",},type: {type: String,},fontFamily: {type: String,default: "iconfont",},
});onBeforeMount(() => {if (props.url) {const existingLink = document.querySelector(`link[href="${props.url}"]`);if (!existingLink) {const link = document.createElement("link");link.href = props.url;link.rel = "stylesheet";document.head.appendChild(link);}}
});const className = computed(() => `${props.fontFamily} ${props.type}`);// 计算样式
const newStyle = computed(() => {const style: Record<string, string | number> = {};if (props.size) {style.width = `${props.size}px`;style.height = `${props.size}px`;}if (props.color) {style.color = props.color;}if (props.rotate) {style.transform = `rotate(${props.rotate}deg)`;}return style;
});// 状态管理
const svgContainer = ref<HTMLDivElement>();
const loading = ref(true);
const error = ref(null);// 加载并渲染SVG的函数
const loadAndRenderSvg = async () => {try {// 重置状态loading.value = true;error.value = null;// 使用动态import导入SVG文件,获取原始内容// 加上 ?raw 后,Vite 会直接将 SVG 文件的内容以纯文本字符串的形式返回const svgUrl = "/src/assets/icons/svg/" + props.name + ".svg";const module = await import(svgUrl + "?raw");const svgContent = module.default;// 清空容器if (svgContainer.value) {(svgContainer.value as any).innerHTML = "";}// 创建临时元素解析SVG内容const tempDiv = document.createElement("div");tempDiv.innerHTML = svgContent;// 获取SVG元素const svgElement = tempDiv.querySelector("svg");if (!svgElement) {throw new Error("导入的文件不是有效的SVG");}// 设置SVG属性svgElement.setAttribute("width", props.size + "px");svgElement.setAttribute("height", props.size + "px");if (props.color) {// 替换SVG颜色replaceSvgFillColor(svgElement, props.color);// svg 图片本身没有 fill 时,添加fillsvgElement.setAttribute("fill", props.color);}// 将SVG元素添加到容器if (svgContainer.value) {svgContainer.value.appendChild(svgElement);}} catch (err: any) {error.value = err.message || `无法加载图标: ${props.name}`;} finally {loading.value = false;}
};/*** 替换SVG元素的fill颜色值* @param svgElement 目标SVG元素* @param newColor 新的颜色值(可以是十六进制、rgb、rgba或颜色名称)* @returns 是否成功替换颜色*/
function replaceSvgFillColor(svgElement: SVGElement,newColor: string
): boolean {if (!svgElement) {return false;}try {// 查找所有带有fill属性的路径元素const pathElements = svgElement.querySelectorAll("path[fill]");if (pathElements.length === 0) {return false;}// 替换每个path元素的fill属性pathElements.forEach((path) => {path.setAttribute("fill", newColor);});return true;} catch (error) {return false;}
}// 监听props变化,重新加载图标
watch(() => [props.name, props.size, props.color],() => {loadAndRenderSvg();}
);// 组件挂载时加载图标
onMounted(() => {if (props.name) {loadAndRenderSvg();}
});
</script><template><Iconv-if="props.icon":icon="props.icon":style="newStyle":flip="props.flip"/><template v-else-if="props.name"><!-- 加载状态 --><div v-if="loading" class="loading">加载中...</div><!-- 错误状态 --><div v-if="error" class="error">图标加载失败: {{ error }}</div><!-- SVG容器 - 动态渲染的SVG将插入到这里 --><div ref="svgContainer" v-else></div></template><iv-else="props.type":class="className":style="{fontSize: props.size + 'px',color: props.color,...newStyle,}"style="display: inline-block"></i>
</template>

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

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

相关文章

redis----持久化

Redis 提供了两种主要的持久化机制&#xff0c;用于将内存中的数据保存到磁盘&#xff0c;以防止服务器重启或故障导致数据丢失。这两种机制分别是 RDB&#xff08;Redis Database&#xff09;和 AOF&#xff08;Append Only File&#xff09;。1. RDB 持久化RDB 是 Redis 默认…

Docker快速部署Mongodb主副本集实践

系列文章目录 第一章 Mongodb的主副本集 文章目录系列文章目录前言一、Mongodb基础介绍数据库&#xff08;Database&#xff09;集合&#xff08;Collection&#xff09;文档&#xff08;Document&#xff09;BSON&#xff08;Binary JSON&#xff09;_id&#xff08;主键&…

FC平台安装Windows Server2016并连接V6存储

创建 windows server2016 上传ISO创建虚拟机安装OS 加载光盘挂载成功之后&#xff0c;重启虚拟机重启之后VNC登录即可。在FC上安装windows&#xff0c;安装完成后&#xff0c;必须安装tools工具&#xff0c;不然没有虚拟网卡&#xff0c;无法配置ip地址。Windows主机安装toolsW…

农业XR数字融合工作站,赋能农业专业实践学习

随着数字技术与农业的深度融合&#xff0c;农业专业XR数字融合工作站为农业专业学生提供了沉浸式、交互式的学习体验。农业专业XR数字融合工作站作为集PC、VR、MR技术于一体的软硬件集成平台&#xff0c;通过虚拟仿真、数字孪生等技术手段&#xff0c;有效解决了传统农业教育中…

积分球的使用——简易版

这篇写的比较杂。积分球的功能积分球——测量灯具等光源的总光通量、光效、色温、显色指数等参数。使用方法1.开启积分球系统&#xff08;探测器、光度计、光谱仪&#xff09;&#xff0c;充分预热&#xff08;15-30分钟&#xff09;&#xff0c;使得电子设备稳定&#xff0c;减…

[光学原理与应用-435]:晶体光学 - 晶体的结构-基元/原胞/晶胞/点阵

晶体的结构可通过基元、原胞、晶胞和点阵四个核心概念进行系统描述&#xff0c;它们共同揭示了晶体中原子排列的周期性与对称性规律&#xff0c;具体如下&#xff1a;1. 基元&#xff08;Structure Motif&#xff09;定义&#xff1a;基元是晶体中重复排列的最小结构单元&#…

电脑音频录制 | 系统麦克混录 / 系统声卡直录 | 方法汇总 / 常见问题

注&#xff1a;本文为 “电脑音频录制 ” 相关合辑。 英文引文&#xff0c;机翻未校。 未整理去重&#xff0c;如有内容异常&#xff0c;请看原文。 How to Record Computer Audio in 6 Free Ways 如何用 6 种免费方式录制电脑音频 Sponsored by EaseUS Nov 28, 2023 4:34 a…

2025高教社国赛数学建模竞赛B题完整参考论文(含模型和代码)

2025国赛数学建模竞赛B题完整参考论文 目录 一、 问题重述 1.1 问题背景 1.2 问题回顾与分析 二、 模型假设 三、 符号说明 四、 问题求解与分析 4.1数据预处理 4.2 问题1求解与分析 4.2.1 问题1分析 4.2.2 问题1建模与求解 4.2.3 问题1结果与分析 4.3 问题2求解与分…

OpenSSL 1.0.1e 下载解压和运行方法(小白适用 附安装包)​

openssl-1.0.1e.zip​ 是 OpenSSL 加密工具包的一个旧版本&#xff08;发布于 2013 年左右&#xff09;的 ​源代码压缩包&#xff0c;文件格式是 ZIP 压缩格式。 一、下载与解压 ​下载文件​ 假如你已经有了 openssl-1.0.1e.zip 这个压缩包&#xff0c;就跳过这步。 如果没有…

MapStruct详解

提到属性拷贝&#xff0c;首先想到的BeanUtils。 先简单的回忆下BeanUtils&#xff0c;处理Java Bean之间的属性拷贝&#xff1b;不过由于它是通过反射来拷贝属性&#xff0c;在数据量大一些的时候性能会降低&#xff1b; 且在安全方面也会比较弱&#xff1b; MapStruct是编译期…

8.FC平台模块梳理

文章目录8.FC平台模块梳理8.1. 内存复用技术特点应用价值8.2. 虚拟机启用策略8.3. NUMA8.4. HA高可用8.5. 故障和响应策略8.6. DRS 和 DPM8.7. IMC8.FC平台模块梳理 8.1. 内存复用 内存共享内存交换内存气泡 内存共享&#xff1a;多台虚拟机共享数据内容相同的内存页。内存交换…

贪心算法应用:DNA自组装问题详解

JAVA中的贪心算法应用&#xff1a;DNA自组装问题详解 1. DNA自组装问题概述 DNA自组装(DNA Self-Assembly)是分子计算和纳米技术中的一个重要问题&#xff0c;它利用DNA分子的互补配对特性&#xff0c;通过精心设计DNA序列&#xff0c;使其自发地组装成预定的纳米结构。在计算机…

数据湖如何打造统一存储与处理方案(结构化数据、半结构化数据和非结构化数据)

目录 1. 数据湖的“包容哲学”:为什么需要统一方案? 数据湖的核心诉求 案例:零售企业的痛点 2. 存储层设计:给数据找个舒适的家 分区与分层存储 选择存储格式 案例:Parquet的威力 云存储的选择 3. 元数据管理:给数据湖装上“导航仪” 元数据管理的核心组件 主流…

AUTOSAR进阶图解==>AUTOSAR_SWS_TTCANDriver

TTCAN驱动器详细规范 AUTOSAR TTCAN Driver Specification with Enhanced Visual Documentation目录 1. 概述2. TTCAN控制器状态机3. TTCAN模块架构4. TTCAN时间触发操作序列5. TTCAN错误处理流程6. 总结 1. 概述 TTCAN&#xff08;Time-Triggered CAN&#xff09;驱动器是AU…

equals 定义不一致导致list contains错误

错误代码如下&#xff1a;for (int i0;i< rows.size();i) {Row r rows.get(i);if (r.equals(row)) {assertTrue(rows.contains(row));return;}}cassertTrue(rows.contains(row));返回了false&#xff0c;看起来很奇怪&#xff0c;此时equals 定义如下&#xff1a;public bo…

【Python基础】 20 Rust 与 Python 循环语句完整对比笔记

一、基本循环结构对比 Rust 循环类型 // 1. loop - 无限循环 let mut count 0; loop {count 1;if count > 5 {break;} }// 2. while - 条件循环 let mut number 3; while number ! 0 {println!("{}!", number);number - 1; }// 3. for - 迭代循环 for i in 0..…

Redis 在互联网高并发场景下的应用--个人总结

在现代互联网系统中&#xff0c;高并发已经成为常态。无论是电商的秒杀场景、社交平台的热点推荐&#xff0c;还是支付接口的风控&#xff0c;系统需要同时应对成千上万的请求。这时候&#xff0c;Redis 作为一个高性能的内存数据库&#xff0c;凭借其极快的读写速度和丰富的数…

C++笔记之软件设计原则总结

C++笔记之软件设计原则总结 code review 文章目录 C++笔记之软件设计原则总结 1.软件设计的六大原则 2.高内聚与低耦合 2.1.高内聚(High Cohesion) 2.2.低耦合(Low Coupling) 2.3.高内聚与低耦合的关系与重要性 3.DRY(Dont Repeat Yourself)原则 3.1.定义 3.2.好处 3.3.示…

ThreadLocal 深度解析:原理、应用场景与最佳实践

一、ThreadLocal 核心概念与设计哲学​1.1 ThreadLocal 的基本概念​ThreadLocal 是 Java 中提供线程局部变量的类&#xff0c;它允许每个线程创建自己的变量副本&#xff0c;从而实现线程封闭&#xff08;Thread Confinement&#xff09;。简单来说&#xff0c;ThreadLocal 为…

AMD显卡运行GPT-OSS全攻略

AMD显卡运行GPT-OSS全攻略 本文介绍如何在Windows系统上使用AMD显卡&#xff08;以RX 7900XTX为例&#xff09;运行开源GPT-OSS模型。 前置要求 硬件&#xff1a;AMD显卡&#xff08;如RX 7900XTX&#xff0c;具体支持型号参考ROCm文档&#xff09;。软件&#xff1a; Ollam…