Files
miaoDirectory/src/components/miaoLazyDiv.vue
T

95 lines
2.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 只适合用于渲染过程较为复杂的组件,不然可能得不偿失
这么泛用的组件,性能差点也能理解 -->
<template>
<div class="miao-lazy" ref="miaoLazyRoot" :style="!show ? { minHeight, minWidth } : {}">
<slot v-if="show" />
</div>
</template>
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue';
const props = defineProps({
disableLazy: {
type: Boolean,
default: false,
},
// 仅在内容未加载时生效,用于占位
minHeight: {
type: String,
default: 'none',
},
minWidth: {
type: String,
default: 'none',
}
})
const miaoLazyRoot = ref<HTMLDivElement>()
const show = ref<boolean>(props.disableLazy)
const isVisible = (dom: HTMLDivElement) => {
const offset = dom.getBoundingClientRect().top
return offset > 0 && offset < 2000
}
const { showSlot, hideSlot, clearTimer } = (() => {
let timer: any
let timerInterval: any
const clearTimer = () => {
timer && clearTimeout(timer)
timerInterval && clearInterval(timerInterval)
timer = undefined
timerInterval = undefined
}
const hideSlot = () => {
clearTimer()
show.value = false
}
const showSlot = () => {
if (show.value === true) {
return
}
clearTimer()
// timer = setTimeout(() => {
if (!miaoLazyRoot.value || isVisible(miaoLazyRoot.value) === false) {
return
}
show.value = true
timerInterval = setInterval(() => {
if (show.value === false || miaoLazyRoot.value === undefined) {
return
}
if (isVisible(miaoLazyRoot.value) === false) {
hideSlot()
}
}, 1000)
// })
}
return { showSlot, hideSlot, clearTimer }
})()
onMounted(() => {
if (show.value === false) {
let options = {
threshold: 0
};
let observer: IntersectionObserver | undefined = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
showSlot()
// miaoLazyRoot.value && observer?.unobserve(miaoLazyRoot.value)
// observer = undefined
} else {
hideSlot()
}
}, options);
miaoLazyRoot.value && observer.observe(miaoLazyRoot.value);
}
})
onBeforeUnmount(() => {
clearTimer()
})
</script>