gpt4 book ai didi

javascript - 在Vuejs3中如何让sticky header组件在与其他组件相交时改变背景颜色?

转载 作者:行者123 更新时间:2023-12-05 02:30:41 26 4
gpt4 key购买 nike

我只是想知道,如何构建我的代码来使我的粘性 <Header />组件更改其 background-color当与其他组件相交时(在本例中为 <Hero /><Footer />

为了让事情变得更复杂,我使用 vue-router .

链接到我的 CodeSandbox

结构如下:

App.vue

<template>
<ul class="nav">
<li>
<router-link to="/">Home</router-link>
</li>
<li>
<router-link to="/about">About</router-link>
</li>
</ul>
<Header />
<router-view />
</template>

views/Home.vue

<template>
<Child1 />
<Child2 />
<Hero />
<Child3 />
<Footer />
</template>

<script>
import Hero from "@/components/Hero";
import Child1 from "@/components/Child1";
import Child2 from "@/components/Child2";
import Child3 from "@/components/Child3";
import Footer from "@/components/Footer";

export default {
components: {
Hero,
Child1,
Child2,
Child3,
Footer,
},
};
</script>

当我在 yt 上学习一些教程时,作者使用 IntersectionObserver ,所以我想试一试:

标题.vue

<template>
<section
class="header"
>
<div class="header__title"
:class="{
header__scroll: isContrastActive,
}"
>
I am an awesome header that is changing it's background colour <br />
when intersecting with other components
</div>
</section>
</template>

<script>
export default {
data() {
return {
isContrastActive: false,
observer: null
};
},
methods: {
activateObserver() {
this.observer = new IntersectionObserver(
([entry]) => {
console.log("isIntersecting: ", entry.isIntersecting);
if (!entry.isIntersecting) {
this.isContrastActive = true;
} else {
this.isContrastActive = false;
}
},
{ rootMargin: "-5% 0px 0px 0px" }
);
document
.querySelectorAll(".observer")
.forEach((el) => this.observer.observe(el));
},
},
mounted() {
this.activateObserver();
},
};
</script>

<style scoped>
.header {
position: sticky;
top: 0;
width: 100vw;
height: auto;
z-index: 10;
}
.header__title {
background-color: yellow;
color: black;
padding: 8px 4px;
text-align: center;
}
.header__scroll {
background-color: orange;
}
</style>

还添加了 class="observer"<Hero /><Footer />成分。但这似乎不起作用。

我读过,在 vue 中使用 querySelector被认为是反模式。

如果是这种情况,那么我该如何构建我的代码以获得我想要的东西?

提前致谢


编辑1:
我注意到,如果我更改 <Header /> 中的文本组件并保存然后一切似乎工作正常。但是在页面刷新时,它仍然不起作用。

认为 querySelectorAll可能是原因。

解决方案 1:最明显的解决方案当然是:

mounted() {
setTimeout(() => {
this.activateObserver()
}, 500)
},

但这不是一个优雅的解决方案:/。

最佳答案

您使用的代码假设所有观察到的元素都已经在 DOM 中。

您需要使可观察对象对所有页面可用(使用首选的状态管理解决方案)。

您的activateObserver 应该变成:

createObserver() {
someStore().observer = new IntersectionObserver(
([entry]) => {
if (!entry.isIntersecting) {
this.isContrastActive = true;
} else {
this.isContrastActive = false;
}
},
{ rootMargin: "-5% 0px 0px 0px" }
);
}

然后,在任何有观察元素的页面中,使用template refs获取您想要观察的所有元素。在 onMounted 中,您开始观察它们,在 onBeforeUnmount 中,您停止观察它们。

const observed = ref([]);

onMounted(() => {
observed.value.forEach(someStore().observer.observe)
})
onBeforeUnmount(() => {
observed.value.forEach(someStore().observer.unobserve)
})

您如何使用模板引用选择元素与此答案无关。关键是您需要在组件挂载后开始观察引用的 DOM 元素,并在卸载前取消观察它们。


注意:理论上,您的任何 View 都可能在 observer 被添加到商店之前呈现。 (实际上这种情况很少见,因此您可能不需要这个)。

但是,如果是这种情况,您需要为页面中的 observer 创建一个观察者,并且只有在您拥有观察者之后才开始观察,这可能是在页面被挂载之后。

原理很简单:您需要观察者和被观察者才能起作用。 observer在添加到store后可用,observedonMounted后可用,直到onBeforeUnmount在任何页面包含它们。

关于javascript - 在Vuejs3中如何让sticky header组件在与其他组件相交时改变背景颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71778765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com