From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/components/Icon/src/Icon.vue |   86 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/src/components/Icon/src/Icon.vue b/src/components/Icon/src/Icon.vue
new file mode 100644
index 0000000..7e2ec94
--- /dev/null
+++ b/src/components/Icon/src/Icon.vue
@@ -0,0 +1,86 @@
+<script lang="ts" setup>
+import { propTypes } from '@/utils/propTypes'
+import Iconify from '@purge-icons/generated'
+import { useDesign } from '@/hooks/web/useDesign'
+
+defineOptions({ name: 'Icon' })
+
+const { getPrefixCls } = useDesign()
+
+const prefixCls = getPrefixCls('icon')
+
+const props = defineProps({
+  // icon name
+  icon: propTypes.string,
+  // icon color
+  color: propTypes.string,
+  // icon size
+  size: propTypes.number.def(16),
+  // icon svg class
+  svgClass: propTypes.string.def('')
+})
+
+const elRef = ref<ElRef>(null)
+
+const isLocal = computed(() => props.icon?.startsWith('svg-icon:'))
+
+const symbolId = computed(() => {
+  return unref(isLocal) ? `#icon-${props.icon.split('svg-icon:')[1]}` : props.icon
+})
+
+const getIconifyStyle = computed(() => {
+  const { color, size } = props
+  return {
+    fontSize: `${size}px`,
+    height: '1em',
+    color
+  }
+})
+
+const getSvgClass = computed(() => {
+  const { svgClass } = props
+  return `iconify ${svgClass}`
+})
+
+const updateIcon = async (icon: string) => {
+  if (unref(isLocal)) return
+
+  const el = unref(elRef)
+  if (!el) return
+
+  await nextTick()
+
+  if (!icon) return
+
+  const svg = Iconify.renderSVG(icon, {})
+  if (svg) {
+    el.textContent = ''
+    el.appendChild(svg)
+  } else {
+    const span = document.createElement('span')
+    span.className = 'iconify'
+    span.dataset.icon = icon
+    el.textContent = ''
+    el.appendChild(span)
+  }
+}
+
+watch(
+  () => props.icon,
+  (icon: string) => {
+    updateIcon(icon)
+  }
+)
+</script>
+
+<template>
+  <ElIcon :class="prefixCls" :color="color" :size="size">
+    <svg v-if="isLocal" :class="getSvgClass">
+      <use :xlink:href="symbolId" />
+    </svg>
+
+    <span v-else ref="elRef" :class="$attrs.class" :style="getIconifyStyle">
+      <span :class="getSvgClass" :data-icon="symbolId"></span>
+    </span>
+  </ElIcon>
+</template>

--
Gitblit v1.8.0