Vue.js의 nextTick()은 이럴 때 쓰면 좋다

beenvyn·2024년 11월 20일

Vue.js

목록 보기
2/3
post-thumbnail

🫠 DOM에 접근하려고 하는 상황에서 분명 코드 상으로는 맞는 것 같은데 DOM이 비동기적으로 렌더링 돼서 접근이 제대로 안될때 . . .❗
✨ 즉, 코드 상에서 바뀐 데이터를 DOM에도 즉각적으로 반영하고 싶을 때

바로 코드를 통해 살펴보도록 하자...

<script setup>
import { ref } from "vue";

import Empty from "./Empty.vue";
import Observer from "./Observer.vue";

const isLoading = ref(false);
const items = ref([]);
const root = ref(null);

const fetch = async () => {
  isLoading.value = true;
  const result = await store.dispatch(~~~);
  isLoading.value = false;
  if (result?.success) {
    items.value = [...result.data.results];
  }
};

fetch();
</script>

<template>
  <div class="container">
    <Empty v-if="isLoading />
    <div v-else class="root">
      <Community
        v-for="(community, index) in items"
        :key="index"
      />
      <Observer :root='root' />
    </div>
  </div>
</template>

위 코드를 보면 로딩중일 때 (isLoading이 true일 때) 화면에 Empty 컴포넌트를 표시하고 로딩이 완료 됐을 때 Community 컴포넌트를 표시한다. 처음에 fetch()가 실행되어 데이터를 불러오는 과정이 끝나면 isLoading이 false가 된다.
이때 Observer 컴포넌트의 props로 <div v-else class="root">를 전달하고 싶다.

그러면 <div v-else class="root">에 어떻게 접근해야 할까...❓

🥉 onMounted를 사용할 경우

onMounted(() => {
  root.value = document.querySelector(".root");
  console.log("root", root.value);
});

root 요소가 렌더링 되기 위해서는 isLoading 값이 false여야 하는데 onMountedfetch()에서 데이터를 불러오는 과정이 완료되어 isLoading 값이 false가 되기 전에 실행되어 root가 null로 출력된다.

🥈 watch를 사용할 경우

watch(isLoading, (isLoading) => {
  if (!isLoading) {
    root.value = document.querySelector(".root");
    console.log("root", root.value);
  }
});

isLoading 값에 watch를 걸어 isLoading 값이 false일 때 root 요소에 접근하려고 했으나 또 다시 null이 출력된다. isLoading이 false가 될 때까지 기다렸지만 실패한 이유는 Vue가 DOM 업데이트를 비동기적으로 하기 때문에 DOM이 그려지기 전에 root 요소에 접근했기 때문이다.

이러한 상황에서 사용하는게 nextTick이다..

🥇 watch와 nextTick을 사용할 경우

watch(isLoading, (isLoading) => {
  if (!isLoading) {
    nextTick(() => {
      root.value = document.querySelector(".root");
      console.log("root", root.value);
    });
  }
});

드디어 성공!!😊
isLoading 값이 false로 변경된 후 nextTick을 사용해서 Vue가 DOM 업데이트를 마쳤을 때 root 요소에 접근하도록 하면 내가 원했던대로 동작한다.

profile
୧ʕ•̀ᴥ•́ʔ୨

0개의 댓글