houzhongjian
2024-12-04 bb203eb72ee4604be8c9272cc583ecb9e393aeb8
提交 | 用户 | 时间
820397 1 <script lang="ts" setup>
H 2 import { propTypes } from '@/utils/propTypes'
6baa33 3 // import Iconify from '@purge-icons/generated'
H 4
820397 5 import { useDesign } from '@/hooks/web/useDesign'
H 6
7 defineOptions({ name: 'Icon' })
8
9 const { getPrefixCls } = useDesign()
10
11 const prefixCls = getPrefixCls('icon')
12
13 const props = defineProps({
14   // icon name
15   icon: propTypes.string,
16   // icon color
17   color: propTypes.string,
18   // icon size
19   size: propTypes.number.def(16),
20   // icon svg class
21   svgClass: propTypes.string.def('')
22 })
23
24 const elRef = ref<ElRef>(null)
25
26 const isLocal = computed(() => props.icon?.startsWith('svg-icon:'))
27
28 const symbolId = computed(() => {
29   return unref(isLocal) ? `#icon-${props.icon.split('svg-icon:')[1]}` : props.icon
30 })
31
32 const getIconifyStyle = computed(() => {
33   const { color, size } = props
34   return {
35     fontSize: `${size}px`,
36     height: '1em',
37     color
38   }
39 })
40
41 const getSvgClass = computed(() => {
42   const { svgClass } = props
43   return `iconify ${svgClass}`
44 })
45
46 const updateIcon = async (icon: string) => {
47   if (unref(isLocal)) return
48
49   const el = unref(elRef)
50   if (!el) return
51
52   await nextTick()
53
54   if (!icon) return
55
56   const svg = Iconify.renderSVG(icon, {})
57   if (svg) {
58     el.textContent = ''
59     el.appendChild(svg)
60   } else {
61     const span = document.createElement('span')
62     span.className = 'iconify'
63     span.dataset.icon = icon
64     el.textContent = ''
65     el.appendChild(span)
66   }
67 }
68
69 watch(
70   () => props.icon,
71   (icon: string) => {
72     updateIcon(icon)
73   }
74 )
75 </script>
76
77 <template>
78   <ElIcon :class="prefixCls" :color="color" :size="size">
79     <svg v-if="isLocal" :class="getSvgClass" aria-hidden="true">
80       <use :xlink:href="symbolId" />
81     </svg>
82
83     <span v-else ref="elRef" :class="$attrs.class" :style="getIconifyStyle">
84       <span :class="getSvgClass" :data-icon="symbolId"></span>
85     </span>
86   </ElIcon>
87 </template>