使用Vue3,我正在尝试创建一个集成了lazyload的Picture组件。
当我加载页面并且所有图片都不在视口中时,一切正常(当我向下滚动时,图像会被连续加载)。
但是,当页面加载并且其中一个图片已经在视口中时,它将加载所有其他不可见的图像。
这里是图片组件
<template>
<div
class="picture"
v-lazy-load="!!placeholder"
>
<img
data-placeholder
class="picture__placeholder"
:src="/^http/.test(placeholder) ? placeholder : require(`@/assets/images/${placeholder}`)"
v-if="placeholder"
>
<img
data-image
class="picture__image"
:alt="alt"
:data-url="/^http/.test(src) ? src : require(`@/assets/images/${src}`)"
>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { DirectiveElement } from '@/scripts/contracts/interfaces'
export default defineComponent({
name: 'Picture',
directives: {
'lazy-load': {
mounted(el: DirectiveElement, binding) {
const image = el.querySelector('.picture__image') as HTMLImageElement
if (!image) {
console.error('[v-lazy-load] provided component doesn\'t contain element with class \'image\'')
return false
}
if (typeof binding.value !== 'boolean') {
console.error('[v-lazy-load] provided value is not a boolean')
return false
}
if (Object.keys(binding.modifiers).length) console.warn('[v-lazy-load] no modifiers allowed')
function loadImage() {
if (image) {
el.eventFn = () => el.classList.add('picture--loaded')
image.addEventListener('load', el.eventFn)
el.eventError = () => console.error('[v-lazy-load] error eventlistener')
image.addEventListener('error', el.eventError)
image.src = image.dataset.url as string
}
}
function handleIntersect(
entries: IntersectionObserverEntry[],
observer: IntersectionObserver,
) {
entries.forEach((entry) => {
if (entry.isIntersecting) {
loadImage()
observer.unobserve(el)
}
})
}
function createObserver() {
const options = { root: null, threshold: 0 }
const observer = new IntersectionObserver(handleIntersect, options)
observer.observe(el)
}
if (window.IntersectionObserver && binding.value) return createObserver()
return loadImage()
},
unmounted(el: DirectiveElement) {
const image = el.querySelector('.picture__image') as HTMLImageElement
if (image) {
image.removeEventListener('load', el.eventFn as EventListener)
image.removeEventListener('error', el.eventError as EventListener)
}
},
},
},
props: {
alt: { type: String, default: '' },
src: { type: String, required: true },
placeholder: { type: String, default: '' },
},
})
</script>
此处是父级组件
<template>
<div class="parent">
<Picture
src="desert.jpg"
style="width: 80%;"
placeholder="placeholder.png"
/>
...
<Picture
src="mountain.jpg"
style="width: 80%;"
placeholder="placeholder.png"
/>
</div>
</template>
有人可以帮我吗?