likes
comments
collection
share

vite 中我是如何封装 svg?

作者站长头像
站长
· 阅读数 14

前言

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

vite 中我是如何封装 svg?

组件规划

svg地址可配置

src目录新建plugins/svgIcons.ts:

/**
 * 配置图标属性
 * 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语法。

<!-- 使用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图标,暴露出四个属性:图标名称(必填)、宽度、高度、填充颜色。

<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>

效果展示

上面的图标如下图所示

vite 中我是如何封装 svg?