diff --git a/packages/uni-components/src/vue/image/index.tsx b/packages/uni-components/src/vue/image/index.tsx index 5e1093f1f88..1dfffeb01d9 100644 --- a/packages/uni-components/src/vue/image/index.tsx +++ b/packages/uni-components/src/vue/image/index.tsx @@ -135,7 +135,32 @@ function useImageLoader( state.origHeight = height state.imgSrc = imgSrc } - const loadImage = (src: string) => { + + const observer = ref() + const cleanupObserver = () => { + if (observer.value) { + observer.value?.disconnect() + observer.value = undefined + } + } + const lazyLoadImage = (src: string) => { + resetImage() + setState() + if (!observer.value) { + observer.value = new IntersectionObserver(([{ isIntersecting }]) => { + if (isIntersecting) { + _loadImage(src) + cleanupObserver() + } + }) + observer.value.observe(state.rootEl!) + } + } + + const loadImage = (src: string) => + props.lazyLoad ? lazyLoadImage(src) : _loadImage(src) + + const _loadImage = (src: string) => { if (!src) { resetImage() setState() @@ -192,7 +217,10 @@ function useImageLoader( } ) onMounted(() => loadImage(state.src)) - onBeforeUnmount(() => resetImage()) + onBeforeUnmount(() => { + cleanupObserver() + resetImage() + }) } const isChrome = __NODE_JS__ ? false : navigator.vendor === 'Google Inc.'