diff --git a/packages/components/avatar/src/avatarImage.ts b/packages/components/avatar/src/avatarImage.ts index fc093cb7d..ecf297f82 100644 --- a/packages/components/avatar/src/avatarImage.ts +++ b/packages/components/avatar/src/avatarImage.ts @@ -1,5 +1,5 @@ import type { ComponentPublicInstance, PropType } from 'vue' -import { computed, defineComponent, h, onMounted, ref, watch } from 'vue' +import { computed, defineComponent, h, onMounted, ref, toRefs, watch } from 'vue' import type { ElementType, MergeProps, PrimitiveProps, RefElement } from '@oku-ui/primitive' import { Primitive } from '@oku-ui/primitive' import type { Scope } from '@oku-ui/provide' @@ -30,9 +30,14 @@ const AvatarImage = defineComponent({ type: Object as unknown as PropType, required: false, }, + src: { + type: String, + required: true, + }, }, setup(props, { attrs, slots, expose }) { - const { src, ...imageProps } = attrs as AvatarImageElement + const { src } = toRefs(props) + const { ...imageProps } = attrs as AvatarImageElement const inject = useAvatarInject(IMAGE_NAME, props.scopeAvatar) const innerRef = ref() const imageLoadingStatus = useImageLoadingStatus(src) @@ -60,7 +65,7 @@ const AvatarImage = defineComponent({ ? h( Primitive.img, { ...imageProps, - src, + src: src.value, ref: innerRef, }, { diff --git a/packages/components/avatar/src/utils.ts b/packages/components/avatar/src/utils.ts index f16c9d8b8..7972fd2a0 100644 --- a/packages/components/avatar/src/utils.ts +++ b/packages/components/avatar/src/utils.ts @@ -1,21 +1,22 @@ -import { onMounted, onUnmounted, ref } from 'vue' +import type { Ref } from 'vue' +import { onBeforeUnmount, ref, watchEffect } from 'vue' export type ImageLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error' -export function useImageLoadingStatus(src?: string) { +export function useImageLoadingStatus(src: Ref) { + const mounted = ref(true) const loadingStatus = ref('idle') - onMounted(() => { + watchEffect(() => { if (!src) { loadingStatus.value = 'error' return } - let isMounted = true const image = new window.Image() const updateStatus = (status: ImageLoadingStatus) => () => { - if (!isMounted) + if (!mounted.value) return loadingStatus.value = status } @@ -23,11 +24,11 @@ export function useImageLoadingStatus(src?: string) { loadingStatus.value = 'loading' image.onload = updateStatus('loaded') image.onerror = updateStatus('error') - image.src = src + image.src = src.value + }) - onUnmounted(() => { - isMounted = false - }) + onBeforeUnmount(() => { + mounted.value = false }) return loadingStatus