Files
reader-star/apps/admin/src/components/custom/svg-icon.vue

58 lines
1.4 KiB
Vue
Raw Normal View History

2026-01-16 13:06:44 +08:00
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import { computed, useAttrs } from 'vue'
defineOptions({ name: 'SvgIcon', inheritAttrs: false })
const props = defineProps<Props>()
/**
* 属性
2026-01-16 13:06:44 +08:00
*
* - 支持 iconify 和本地 svg 图标
* - 如果同时传递了 icon localIcon将优先渲染 localIcon
2026-01-16 13:06:44 +08:00
*/
interface Props {
/** Iconify 图标名称 */
2026-01-16 13:06:44 +08:00
icon?: string
/** 本地 svg 图标名称 */
2026-01-16 13:06:44 +08:00
localIcon?: string
}
const attrs = useAttrs()
const bindAttrs = computed<{ class: string, style: string }>(() => ({
class: (attrs.class as string) || '',
style: (attrs.style as string) || '',
}))
// 本地 svg 图标 id 格式:#icon-local-{icon}
2026-01-16 13:06:44 +08:00
const symbolId = computed(() => {
const { VITE_ICON_LOCAL_PREFIX: prefix } = import.meta.env // icon-local
2026-01-16 13:06:44 +08:00
const defaultLocalIcon = 'no-icon'
const icon = props.localIcon || defaultLocalIcon
return `#${prefix}-${icon}`
})
/** 如果传递了 localIcon则优先渲染 localIcon */
2026-01-16 13:06:44 +08:00
const renderLocalIcon = computed(() => props.localIcon || !props.icon)
</script>
<template>
<!-- 渲染本地 svg 图标 -->
2026-01-16 13:06:44 +08:00
<template v-if="renderLocalIcon">
<svg aria-hidden="true" width="1em" height="1em" v-bind="bindAttrs">
<use :xlink:href="symbolId" fill="currentColor" />
</svg>
</template>
<template v-else>
<!-- 渲染 iconify 图标 -->
2026-01-16 13:06:44 +08:00
<Icon v-if="icon" :icon="icon" v-bind="bindAttrs" />
</template>
</template>
<style scoped></style>