到現(xiàn)在為止,我肯定已經(jīng)嘗試了十幾種不同的代碼——都沒有用——讓Vue與IntersectionObserver一起工作。
下面的代碼不顯示任何內(nèi)容。我可以做什么樣的更改,以便截面在與視口相交時(shí)變得可見?
App.vue:
<template>
<section class="hidden">
<h1>Title</h1>
<p>Some text</p>
</section>
<section class="hidden">
<h2>More text</h2>
</section>
</template>
<style scoped>
* {
background-color: 131313;
padding: 0;
margin: 0;
}
section {
display: grid;
place-items: center;
align-content: center;
min-height: 100vh;
}
.hidden {
opacity: 0.5;
transition: all 1s;
}
.show {
opacity: 1;
}
</style>
<script setup>
import { onMounted } from "vue";
onMounted(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
console.log(entry);
if (entry.intersectionRatio > 0) {
entry.target.classList.add("show");
} else {
entry.target.classList.remove("show");
}
});
});
const hiddenElements = document.querySelectorAll(".hidden");
hiddenElements.forEach((el) => observer.observe(el));
});
</script>
這是這篇文章的后續(xù)。
你提供的代碼似乎大部分都能工作,但這不是我們?cè)赩ue中做事的方式。在Vue中,您應(yīng)該使用模板引用來引用組件,而不是使用querySelector,并且您還應(yīng)該使用引用來更改模板中的類,而不是自己直接修改DOM(Vue的反應(yīng)系統(tǒng)不能跟蹤您自己手動(dòng)進(jìn)行的更改,并且可能隨時(shí)覆蓋它們)。為了使上面的一切更容易,我們需要使這個(gè)部分成為它自己的組件。
App.vue:
<template>
<div style="height: 1000px; background: red"></div>
<Section>
<h1>Title</h1>
<p>Some text</p>
</Section>
<Section>
<h2>More text</h2>
</Section>
</template>
<style scoped>
* {
background-color: 131313;
padding: 0;
margin: 0;
}
</style>
<script setup>
import Section from './Section.vue'
</script>
Section.vue:
<template>
<section class="hidden" :class="{show}" ref="section">
<slot></slot>
</section>
</template>
<style sciped>
section {
display: grid;
place-items: center;
align-content: center;
min-height: 100vh;
}
.hidden {
opacity: 0.5;
transition: all 2s;
}
.show {
opacity: 1;
background: blue;
}
</style>
<script setup>
import { onMounted, ref } from "vue";
const section = ref(null);
const show = ref(false);
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
console.log(entry);
show.value = entry.isIntersecting;
});
});
onMounted(() => observer.observe(section.value));
</script>
現(xiàn)場(chǎng)演示:Vue SFC游樂場(chǎng)
在示例中,我還使用is intersecting屬性來確定元素是否相交,而不是使用比率。