先看效果
代码
<template>
<main class="w-full h-full p-5 overflow-x-hidden">
<ScrollBox animate="zoomIn">
<template #default="{ useRandomBg }">
<div class="p-10 h-[200px] my-2 cursor-pointer" v-for="item in 100" :key="item" :style="useRandomBg()">
box{{ item }}
</div>
</template>
</ScrollBox>
</main>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>
ScrollBox组件
<template>
<div ref="mainRef" class="w-full h-full">
<slot :useRandomBg="useRandomBg"></slot>
</div>
</template>
<script lang="ts" setup>
import { useRandomBg } from '@/hooks/useRandomBg'
const props = withDefaults(
defineProps<{
/**
* 过度动画名称
* default ==> fadeInRight
* 参考 https://animate.style/
*/
animate?: string
/**过渡时间 default ==> 0.5s */
delay?: string
}>(),
{
animate: 'fadeInRight',
delay: '0.5s',
},
)
const mainRef = ref()
let observer: IntersectionObserver
onMounted(() => {
Array.from(mainRef.value.children as NodeListOf<Element>).map((e) => {
observer = new IntersectionObserver((entries) => {
// 可见性变化处理
entries.forEach((entry) => {
/** 元素可见*/
if (entry.isIntersecting) {
e.classList.add('animate__animated')
e.classList.add('animate__' + props.animate)
e.classList.add('animate__delay-' + props.delay)
} else {
// e.classList.remove('animate__animated')
// e.classList.remove('animate__' + props.animate)
// e.classList.remove('animate__delay-' + props.delay)
// console.log(`元素不可见 ==>`)
}
})
})
observer.observe(e)
})
})
onUnmounted(() => (observer = null))
</script>
<style lang="scss"></style>
组件使用animate.css实现过度效果 需要引入
pnpm i animate.css
import 'animate.css'
需要想要的效果直接去animate.css官网 复制类名就可以直接使用了
<ScrollBox animate="zoomIn">
...
</ScrollBox>