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>

效果展示

上面的图标如下图所示

相关推荐
arvin_xiaoting3 小时前
OpenClaw学习总结_I_核心架构_8:SessionPruning详解
前端·chrome·学习·系统架构·ai agent·openclaw·sessionpruning
工程师老罗4 小时前
Image(图像)的用法
java·前端·javascript
早點睡3904 小时前
ReactNative项目OpenHarmony三方库集成实战:react-native-swiper
javascript·react native·react.js
jump_jump5 小时前
深入 JavaScript Iterator Helpers:从 API 到引擎实现
javascript·性能优化
swipe5 小时前
把 JavaScript 原型讲透:从 `[[Prototype]]`、`prototype` 到 `constructor` 的完整心智模型
前端·javascript·面试
问道飞鱼5 小时前
【前端知识】React 组件生命周期:从底层原理到实践场景
前端·react.js·前端框架·生命周期
Dxy12393102165 小时前
JS发送请求的方法详解
开发语言·javascript·ecmascript
CHU7290355 小时前
定制专属美丽时刻:美容预约商城小程序的贴心设计
前端·小程序
浩~~6 小时前
反射型XSS注入
前端·xss
AwesomeDevin6 小时前
AI时代,我们的任务不应沉溺于与 AI 聊天,🤔 从“对话式编程”迈向“数字软件工厂”
前端·后端·架构