chore(Icon): improve component

This commit is contained in:
Benjamin Canac
2022-07-13 16:45:39 +02:00
parent 95c018f63f
commit 498be15a29

View File

@@ -1,33 +1,38 @@
<template> <template>
<Iconify v-if="icon" :icon="icon" /> <span v-if="isFetching" />
<Iconify v-else-if="icon" :icon="icon" />
<Component :is="component" v-else-if="component" /> <Component :is="component" v-else-if="component" />
<span v-else>{{ name }}</span> <span v-else>{{ name }}</span>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import type { Ref } from 'vue'
import type { IconifyIcon } from '@iconify/vue' import type { IconifyIcon } from '@iconify/vue'
import { ref, watch, computed } from 'vue' import { computed, ref, watch } from 'vue'
import { Icon as Iconify } from '@iconify/vue/dist/offline' import { Icon as Iconify } from '@iconify/vue/dist/offline'
import { loadIcon } from '@iconify/vue' import { loadIcon } from '@iconify/vue'
import { useNuxtApp } from '#imports' import { useNuxtApp, useState } from '#imports'
const nuxtApp = useNuxtApp()
const props = defineProps({ const props = defineProps({
name: { name: {
type: String, type: String,
required: true required: true
} }
}) })
const nuxtApp = useNuxtApp()
const icon: Ref<IconifyIcon | null> = ref(null) const state = useState('u-icons', () => ({}))
const isFetching = ref(false)
const icon = computed<IconifyIcon | null>(() => state.value?.[props.name])
const component = computed(() => nuxtApp.vueApp.component(props.name)) const component = computed(() => nuxtApp.vueApp.component(props.name))
const loadIconComponent = async () => {
icon.value = await loadIcon(props.name).catch(_ => null) if (component.value) { return }
if (!state.value?.[props.name]) {
watch(() => props.name, async () => { isFetching.value = true
icon.value = await loadIcon(props.name).catch(_ => null) state.value[props.name] = await loadIcon(props.name).catch(() => null)
}) isFetching.value = false
}
}
watch(() => props.name, loadIconComponent)
!component.value && (await loadIconComponent())
</script> </script>
<script lang="ts"> <script lang="ts">