1

I'm trying to initialise IntersectionObserver in each page of my website built with Nuxt3.

Therefore, I want to access each HTML element that has a specific CSS class. However, on page change, I noticed that via onMounted hook the detected elements are from the previous page.

Here a easy to reproduce example:

app.vue

<template>
  <div>
    <NuxtPage />
  </div>
</template>

pages/index.vue

<script setup lang="ts">
onMounted(() => {
  console.group("index.vue");
  console.log(document.querySelector("#container"));
  console.groupEnd();
});
</script>

<template>
  <div id="container">
    <h1>INDEX</h1>
    <NuxtLink to="/work">
      Go to work
    </NuxtLink>
  </div>
</template>

pages/work.vue

<script setup lang="ts">
onMounted(() => {
  console.group("work.vue");
  console.log(document.querySelector("#container"));
  console.groupEnd();
});
</script>

<template>
  <div id="container">
    <h1>WORK</h1>
    <NuxtLink to="/">
      Go to index
    </NuxtLink>
  </div>
</template>

Simply, the result in the console always come from the previous DOM. Here the steps:

  • Load the page on index.vue, you see the right element in the console.
  • Go to work.vue using the link.
  • See the console showing the exact same result as previously, yet with an added empty class attribute on #container

My question is, why does onMounted hook doesn't show the right DOM on page change?

I tried to set the page transition to the default mode:

definePageMeta({
  pageTransition: {
    mode: 'default',
  },
});

Nothing changed.

NOTE: I am using nuxt version: 3.0.0-rc.9

kissu
  • 40,416
  • 14
  • 65
  • 133
ThomasG2201
  • 676
  • 6
  • 25
  • Mainly because you're not supposed to use any kind of querySelector but rather rely on state (Vue is a state based framework). So, I recommend you targeting those same elements but with a template ref rather. – kissu Sep 04 '22 at 17:37
  • Yeah, but I think this behaviour is not obvious. It seems strange. My problem is solved using refs. Instead of using `document` I give a ref to a container and then use `querySelector` on it. Works perfectly fine. Thank you – ThomasG2201 Sep 04 '22 at 18:38

1 Answers1

1

For this kind of usage, you should use template refs: https://vuejs.org/guide/essentials/template-refs.html#accessing-the-refs

Otherwise, Vue will not behave as expected. More details can be found in this other answer.

kissu
  • 40,416
  • 14
  • 65
  • 133