기록

vue.js nuxt.js IntersectionObserver 사용하여 무한 스크롤 구현하기 본문

TIL*

vue.js nuxt.js IntersectionObserver 사용하여 무한 스크롤 구현하기

mnmhbbb 2024. 11. 1. 22:40

유저의 스크롤 위치를 감지하여 다음 페이지를 불러오는 무한스크롤 기능을 구현하였다.

목록을 불러오는 컴포넌트는 이러하다.

<template>
  <!-- ... --> 
  <scroll-observer
    v-if="hasNextPage"
    @load-more="loadMoreList"
  />
</template>

<script setup lang="ts">
// ...

const loadMoreList = async () => {
  currentPage.value++;
  pageRequest.value = {
    ...pageRequest.value,
    page: currentPage.value,
  };
  await fetchSearch(category.value as string[], true);
};

</script>

위와 같이 ScrollObserver 컴포넌트를 사용하고 있다.
ScrollObserver 내의 특정 엘리먼트가 화면에 나타나면, emit을 통해 이벤트를 발생시켜서 loadMoreList 메서드를 호출하기 위함이다.

ScrollObserver 컴포넌트는 이렇게 구성하였다.

<template>
  <div ref="observer">
    <div class="my-20 flex items-center justify-center">
      <p-progress-spinner
        animation-duration=".5s"
        aria-label="Custom ProgressSpinner"
        fill="transparent"
        stroke-width="8"
        style="width: 50px; height: 50px"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
const emit = defineEmits<{
  (e: "load-more"): void;
}>();

const observer: Ref<HTMLDivElement | null> = ref(null);

let intersectionObserver: IntersectionObserver;

onMounted(() => {
  intersectionObserver = new IntersectionObserver(([entry]) => {
    if (entry.isIntersecting) {
      emit("load-more");
    }
  });
  if (observer.value) {
    intersectionObserver.observe(observer.value);
  }
});

onBeforeUnmount(() => {
  if (observer.value) {
    intersectionObserver.unobserve(observer.value);
  }
  intersectionObserver.disconnect();
});
</script>

 

 

 

Comments