Skip to content

Commit

Permalink
refactor: image watchEffect (#245)
Browse files Browse the repository at this point in the history
  • Loading branch information
productdevbook committed Jul 23, 2023
1 parent 427be5e commit 2f44a96
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
11 changes: 8 additions & 3 deletions packages/components/avatar/src/avatarImage.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -30,9 +30,14 @@ const AvatarImage = defineComponent({
type: Object as unknown as PropType<Scope>,
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<ComponentPublicInstance>()
const imageLoadingStatus = useImageLoadingStatus(src)
Expand Down Expand Up @@ -60,7 +65,7 @@ const AvatarImage = defineComponent({
? h(
Primitive.img, {
...imageProps,
src,
src: src.value,
ref: innerRef,
},
{
Expand Down
19 changes: 10 additions & 9 deletions packages/components/avatar/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
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<string>) {
const mounted = ref(true)
const loadingStatus = ref<ImageLoadingStatus>('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
}

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
Expand Down

0 comments on commit 2f44a96

Please sign in to comment.