Commit e8fe6a929be025a889ddec624ff9c2729313c818
1 parent
9e3adaa3
perf(icon): icon and SvgIcon integration
Showing
1 changed file
with
33 additions
and
21 deletions
src/components/Icon/src/index.vue
1 | <template> | 1 | <template> |
2 | - <span ref="elRef" :class="[$attrs.class, 'app-iconify anticon']" :style="getWrapStyle"></span> | 2 | + <SvgIcon :size="size" :name="getSvgIcon" v-if="isSvgIcon" :class="[$attrs.class]" /> |
3 | + <span | ||
4 | + v-else | ||
5 | + ref="elRef" | ||
6 | + :class="[$attrs.class, 'app-iconify anticon']" | ||
7 | + :style="getWrapStyle" | ||
8 | + ></span> | ||
3 | </template> | 9 | </template> |
4 | <script lang="ts"> | 10 | <script lang="ts"> |
5 | import type { PropType } from 'vue'; | 11 | import type { PropType } from 'vue'; |
@@ -13,12 +19,16 @@ | @@ -13,12 +19,16 @@ | ||
13 | computed, | 19 | computed, |
14 | CSSProperties, | 20 | CSSProperties, |
15 | } from 'vue'; | 21 | } from 'vue'; |
22 | + | ||
23 | + import SvgIcon from './SvgIcon.vue'; | ||
16 | import Iconify from '@purge-icons/generated'; | 24 | import Iconify from '@purge-icons/generated'; |
17 | import { isString } from '/@/utils/is'; | 25 | import { isString } from '/@/utils/is'; |
18 | import { propTypes } from '/@/utils/propTypes'; | 26 | import { propTypes } from '/@/utils/propTypes'; |
19 | 27 | ||
28 | + const SVG_END_WITH_FLAG = '|svg'; | ||
20 | export default defineComponent({ | 29 | export default defineComponent({ |
21 | name: 'GIcon', | 30 | name: 'GIcon', |
31 | + components: { SvgIcon }, | ||
22 | props: { | 32 | props: { |
23 | // icon name | 33 | // icon name |
24 | icon: propTypes.string, | 34 | icon: propTypes.string, |
@@ -34,28 +44,30 @@ | @@ -34,28 +44,30 @@ | ||
34 | setup(props) { | 44 | setup(props) { |
35 | const elRef = ref<ElRef>(null); | 45 | const elRef = ref<ElRef>(null); |
36 | 46 | ||
37 | - const getIconRef = computed(() => { | ||
38 | - const { icon, prefix } = props; | ||
39 | - return `${prefix ? prefix + ':' : ''}${icon}`; | ||
40 | - }); | 47 | + const isSvgIcon = computed(() => props.icon?.endsWith(SVG_END_WITH_FLAG)); |
48 | + const getSvgIcon = computed(() => props.icon.replace(SVG_END_WITH_FLAG, '')); | ||
49 | + const getIconRef = computed(() => `${props.prefix ? props.prefix + ':' : ''}${props.icon}`); | ||
41 | 50 | ||
42 | const update = async () => { | 51 | const update = async () => { |
52 | + if (unref(isSvgIcon)) return; | ||
53 | + | ||
43 | const el = unref(elRef); | 54 | const el = unref(elRef); |
44 | - if (el) { | ||
45 | - await nextTick(); | ||
46 | - const icon = unref(getIconRef); | ||
47 | - if (!icon) return; | ||
48 | - const svg = Iconify.renderSVG(icon, {}); | ||
49 | - if (svg) { | ||
50 | - el.textContent = ''; | ||
51 | - el.appendChild(svg); | ||
52 | - } else { | ||
53 | - const span = document.createElement('span'); | ||
54 | - span.className = 'iconify'; | ||
55 | - span.dataset.icon = icon; | ||
56 | - el.textContent = ''; | ||
57 | - el.appendChild(span); | ||
58 | - } | 55 | + if (!el) return; |
56 | + | ||
57 | + await nextTick(); | ||
58 | + const icon = unref(getIconRef); | ||
59 | + if (!icon) return; | ||
60 | + | ||
61 | + const svg = Iconify.renderSVG(icon, {}); | ||
62 | + if (svg) { | ||
63 | + el.textContent = ''; | ||
64 | + el.appendChild(svg); | ||
65 | + } else { | ||
66 | + const span = document.createElement('span'); | ||
67 | + span.className = 'iconify'; | ||
68 | + span.dataset.icon = icon; | ||
69 | + el.textContent = ''; | ||
70 | + el.appendChild(span); | ||
59 | } | 71 | } |
60 | }; | 72 | }; |
61 | 73 | ||
@@ -78,7 +90,7 @@ | @@ -78,7 +90,7 @@ | ||
78 | 90 | ||
79 | onMounted(update); | 91 | onMounted(update); |
80 | 92 | ||
81 | - return { elRef, getWrapStyle }; | 93 | + return { elRef, getWrapStyle, isSvgIcon, getSvgIcon }; |
82 | }, | 94 | }, |
83 | }); | 95 | }); |
84 | </script> | 96 | </script> |