Browse Source

perf(icon): icon and SvgIcon integration

Vben 4 years ago
parent
commit
e8fe6a929b
1 changed files with 33 additions and 21 deletions
  1. 33 21
      src/components/Icon/src/index.vue

+ 33 - 21
src/components/Icon/src/index.vue

@@ -1,5 +1,11 @@
 <template>
-  <span ref="elRef" :class="[$attrs.class, 'app-iconify anticon']" :style="getWrapStyle"></span>
+  <SvgIcon :size="size" :name="getSvgIcon" v-if="isSvgIcon" :class="[$attrs.class]" />
+  <span
+    v-else
+    ref="elRef"
+    :class="[$attrs.class, 'app-iconify anticon']"
+    :style="getWrapStyle"
+  ></span>
 </template>
 <script lang="ts">
   import type { PropType } from 'vue';
@@ -13,12 +19,16 @@
     computed,
     CSSProperties,
   } from 'vue';
+
+  import SvgIcon from './SvgIcon.vue';
   import Iconify from '@purge-icons/generated';
   import { isString } from '/@/utils/is';
   import { propTypes } from '/@/utils/propTypes';
 
+  const SVG_END_WITH_FLAG = '|svg';
   export default defineComponent({
     name: 'GIcon',
+    components: { SvgIcon },
     props: {
       // icon name
       icon: propTypes.string,
@@ -34,28 +44,30 @@
     setup(props) {
       const elRef = ref<ElRef>(null);
 
-      const getIconRef = computed(() => {
-        const { icon, prefix } = props;
-        return `${prefix ? prefix + ':' : ''}${icon}`;
-      });
+      const isSvgIcon = computed(() => props.icon?.endsWith(SVG_END_WITH_FLAG));
+      const getSvgIcon = computed(() => props.icon.replace(SVG_END_WITH_FLAG, ''));
+      const getIconRef = computed(() => `${props.prefix ? props.prefix + ':' : ''}${props.icon}`);
 
       const update = async () => {
+        if (unref(isSvgIcon)) return;
+
         const el = unref(elRef);
-        if (el) {
-          await nextTick();
-          const icon = unref(getIconRef);
-          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);
-          }
+        if (!el) return;
+
+        await nextTick();
+        const icon = unref(getIconRef);
+        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);
         }
       };
 
@@ -78,7 +90,7 @@
 
       onMounted(update);
 
-      return { elRef, getWrapStyle };
+      return { elRef, getWrapStyle, isSvgIcon, getSvgIcon };
     },
   });
 </script>