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