前言
使用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>
效果展示
上面的图标如下图所示