<template>
<i v-if="isShowIconSvg" class="el-icon" :style="setIconSvgStyle">
<component :is="getIconName" />
</i>
<div v-else-if="isShowIconImg" :style="setIconImgOutStyle">
<img :src="getIconName" :style="setIconSvgInsStyle" />
</div>
<Icon v-else-if="getIconName?.indexOf(':') !== -1" :icon="getIconName" :style="setIconSvgStyle"/>
<i v-else :class="getIconName" :style="setIconSvgStyle" />
</template>
<script setup lang="ts" name="svgIcon">
import { computed } from 'vue';
// å®šä¹‰çˆ¶ç»„ä»¶ä¼ è¿‡æ¥çš„值
const props = defineProps({
// svg å›¾æ ‡ç»„ä»¶åå—
name: {
type: String,
},
// svg 大å°
size: {
type: Number,
default: () => 14,
},
// svg 颜色
color: {
type: String,
},
});
// åœ¨çº¿é“¾æŽ¥ã€æœ¬åœ°å¼•入地å€å‰ç¼€
// https://gitee.com/lyt-top/vue-next-admin/issues/I62OVL
const linesString = ['https', 'http', '/src', '/assets', 'data:image', import.meta.env.VITE_PUBLIC_PATH];
// èŽ·å– icon å›¾æ ‡åç§°
const getIconName = computed(() => {
return props?.name;
});
// ç”¨äºŽåˆ¤æ– element plus 自带 svg å›¾æ ‡çš„æ˜¾ç¤ºã€éšè—
const isShowIconSvg = computed(() => {
return props?.name?.startsWith('ele-');
});
// 用于判æ–åœ¨çº¿é“¾æŽ¥ã€æœ¬åœ°å¼•å…¥ç‰å›¾æ ‡æ˜¾ç¤ºã€éšè—
const isShowIconImg = computed(() => {
return linesString.find((str) => props.name?.startsWith(str));
});
// è®¾ç½®å›¾æ ‡æ ·å¼
const setIconSvgStyle = computed(() => {
return `font-size: ${props.size}px;color: ${props.color};`;
});
// è®¾ç½®å›¾ç‰‡æ ·å¼
const setIconImgOutStyle = computed(() => {
return `width: ${props.size}px;height: ${props.size}px;display: inline-block;overflow: hidden;`;
});
// è®¾ç½®å›¾ç‰‡æ ·å¼
// https://gitee.com/lyt-top/vue-next-admin/issues/I59ND0
const setIconSvgInsStyle = computed(() => {
const filterStyle: string[] = [];
const compatibles: string[] = ['-webkit', '-ms', '-o', '-moz'];
compatibles.forEach((j) => filterStyle.push(`${j}-filter: drop-shadow(${props.color} 30px 0);`));
return `width: ${props.size}px;height: ${props.size}px;position: relative;left: -${props.size}px;${filterStyle.join('')}`;
});
</script>
|