vite 中我是如何封装 svg?

前言

使用vite4新建项目的时候,发现项目中的案例使用的svg图标是以组件形式引用的。如下图(vue项目的代码)。于是乎,直接封装一个组件,好像也挺好的。不知道大家是如何看法?

组件规划

svg地址可配置

src目录新建plugins/svgIcons.ts:

arduino 复制代码
/**
 * 配置图标属性
 * iconsConfig.xxx xxx 为图标名称
 * svg: 图标的svg值
 */
export const iconsConfig = {
  // times 为组件名称
  times: {// 这个为对象,就是想着以后可以拓展一些内容
    // 这个地址把svg的拷进去就对了
    svg: '<svg ...><path ...></svg>'
  },
  book:{
    svg: '<svg ...><path ... /></svg>'
  }
}
svg-icons组件

src/components目录下新建svg-icons.vue,以下是使用jsx语法。

xml 复制代码
<!-- 使用jsx 语法,新建项目时要选择这个插件 -->
<!-- 使用jsx 不能用 setup 语法,并且要用lang=jsx -->
<script lang="jsx">
import { defineComponent } from 'vue'
// 这边是将刚才配置的数据直接引入,如果当心性能问题,也可以修改为传入props
import { iconsConfig } from '@/plugins/svgIcons.ts'
​
export default defineComponent({
  name: 'svgIcon',
  props: {
    // 图标名称
    iconName: {
      required: true,
      type: String
    },
    // svg 宽度
    width: Number,
    // svg 高度
    height: Number,
    // 颜色
    fill: String
  },
  setup(props, ctx) {
​
    let { svg } = iconsConfig[props.iconName]
​
    // 修改宽度
    if(props.width){
      let isWidth = svg.indexOf('width')
      svg = isWidth === -1 ? 
            svg.replace(/<svg/, `<svg width=${props.width}`) : 
            svg.replace(/width=".*?"/, `width=${props.width}`) 
    }
    // 修改高度
    if(props.height){
      let isHeight = svg.indexOf('height')
      svg = isHeight === -1 ?
            svg.replace(/<svg/, `<svg height=${props.height}`) :
            svg.replace(/height=".*?"/, `height=${props.height}`)
    }
​
    // 修改颜色
    if(props.fill){
      let isFill = svg.indexOf('fill')
      svg = isFill === -1 ?
            svg.replace(/<svg/, `<svg fill=${props.fill}`) :
            svg.replace(/fill=".*?"/, `fill=${props.fill}`)
    }
​
    return () => <div v-html={ svg }></div>;
  },
})
</script>
组件引入

svg图标,暴露出四个属性:图标名称(必填)、宽度、高度、填充颜色。

xml 复制代码
<script setup lang="ts">
  import SvgIcon from '@/components/svg-icons/index.vue'
</script>
​
<template>
  <!-- 时钟 -->
  <svg-icon 
    iconName="times" 
    width="50" 
    height="50" 
    fill="red"
  >
  </svg-icon>
  <!-- vue 图标 -->
  <svg-icon iconName="book" width="50" height="50"></svg-icon>
</template>

效果展示

上面的图标如下图所示

相关推荐
砚凝霜1 天前
软考网络工程师|案例分析:Eth‑Trunk 链路聚合、iStack 堆叠、CSS 集群核心考点总结
前端·css·网络
二级小助手1 天前
二级Web前端选择题高频真题20道与考场避坑笔记
javascript·css3·html5·web前端·计算机二级·二级web·web真题
珐恩AI-人工智能1 天前
大模型意图召回偏差分析:GEO如何解决“有收录却不触发问答曝光”的难题
大数据·前端·人工智能·html·流量运营·geo优化
程序员老赵1 天前
Docker 部署禅道 ZenTao:轻松搭建研发项目管理平台
前端·后端·github
前端小卡拉1 天前
用了大半年 AI 编程工具,我才搞懂 Skill 到底是什么
前端·javascript
hunterandroid1 天前
[鸿蒙从零到一] HarmonyOS 单元测试与 UI 自动化测试实战:从代码质量到用户体验的全链路保障
前端
郭邯1 天前
用 Intl.DateTimeFormat 手写一个时区转换器,顺便聊聊我和 AI 结对编程的日常
前端·javascript
阿奇__1 天前
微前端、iframe与Auth Code技术方案对比
前端
FungLeo1 天前
React 管理后台实战 · 前端请求层怎么写?401 静默刷新、token 并发竞争、强制改密拦截一次说清
前端·react.js·前端框架
mashirro1 天前
记一次基于ruoyi-vue新增小程序服务模块,小程序登陆相关
vue.js·小程序·mybatis