vben
2020-11-15 661db0c767772bb7a30da9d3eeaf2b47858ccf0b
提交 | 用户 | age
2f6253 1 import type { PropType } from 'vue';
2 import { defineComponent, ref, watch, onMounted, nextTick, unref, computed } from 'vue';
3 import Iconify from '@purge-icons/generated';
4 import { isString } from '/@/utils/is';
5 import './index.less';
6 export default defineComponent({
7   name: 'GIcon',
8   props: {
9     // icon name
10     icon: {
11       type: String as PropType<string>,
12       required: true,
13     },
14     // icon color
15     color: {
16       type: String as PropType<string>,
17     },
18     // icon size
19     size: {
20       type: [String, Number] as PropType<string | number>,
661db0 21       default: 16,
2f6253 22     },
23     prefix: {
24       type: String as PropType<string>,
25       default: '',
26     },
27   },
28   setup(props, { attrs }) {
29     const elRef = ref<Nullable<HTMLElement>>(null);
30
31     const getIconRef = computed(() => {
32       const { icon, prefix } = props;
33       return `${prefix ? prefix + ':' : ''}${icon}`;
34     });
f64568 35
2f6253 36     const update = async () => {
37       const el = unref(elRef);
38       if (el) {
39         await nextTick();
40         const icon = unref(getIconRef);
41
42         const svg = Iconify.renderSVG(icon, {});
43
44         if (svg) {
45           el.textContent = '';
46           el.appendChild(svg);
47         } else {
48           const span = document.createElement('span');
49           span.className = 'iconify';
50           span.dataset.icon = icon;
51           el.textContent = '';
52           el.appendChild(span);
53         }
54       }
55     };
56
57     const wrapStyleRef = computed((): any => {
58       const { size, color } = props;
59       let fs = size;
60       if (isString(size)) {
61         fs = parseInt(size, 10);
62       }
63       return {
64         fontSize: `${fs}px`,
65         color,
03b602 66         display: 'inline-flex',
2f6253 67       };
68     });
69
f96d6b 70     watch(() => props.icon, update, { flush: 'post' });
f64568 71
2f6253 72     onMounted(update);
73
74     return () => (
96c10d 75       <div ref={elRef} class={[attrs.class, 'app-iconify anticon']} style={unref(wrapStyleRef)} />
2f6253 76     );
77   },
78 });