재사용 가능한 페이지네이션 컴포넌트 구축

JavaScriptBeginner
지금 연습하기

소개

이 프로젝트에서는 웹 애플리케이션에서 흔히 사용되는 컴포넌트인 페이지네이션 (pagination) 컴포넌트를 구축하는 방법을 배우게 됩니다. 페이지네이션 컴포넌트는 백엔드에서 쿼리 시간을 줄이는 데 도움이 되며, 너무 많은 데이터 로딩으로 인한 페이지 렌더링 성능 저하를 방지합니다.

👀 미리보기

Pagination component demo

🎯 과제

이 프로젝트에서 다음을 배우게 됩니다:

  • 데이터 요청을 처리하고 현재 페이지의 데이터와 총 페이지 수를 검색하기 위해 ajax 함수를 구현하는 방법.
  • 페이지네이션 컴포넌트의 버튼에 이벤트를 바인딩하기 위해 initEvents 함수를 구현하는 방법.
  • 함수 인수를 기반으로 페이지네이션 배열을 생성하기 위해 createPaginationIndexArr 함수를 구현하는 방법.
  • 페이지네이션 컴포넌트의 문자열 템플릿을 생성하기 위해 renderPagination 함수를 구현하는 방법.
  • 현재 페이지를 기반으로 콘텐츠를 렌더링하는 방법.

🏆 성과

이 프로젝트를 완료하면 다음을 수행할 수 있습니다:

  • JavaScript 로 재사용 가능한 페이지네이션 컴포넌트를 구축할 수 있습니다.
  • Axios 를 사용하여 HTTP 요청을 하고 응답 데이터를 처리할 수 있습니다.
  • 현재 페이지, 총 페이지 수 및 표시할 최대 페이지 버튼 수를 기반으로 페이지네이션 배열을 생성할 수 있습니다.
  • 현재 페이지를 기반으로 페이지네이션 컴포넌트와 콘텐츠를 업데이트할 수 있습니다.

프로젝트 구조 설정

이 단계에서는 프로젝트 파일과 구조를 설정합니다. 이 단계를 완료하려면 아래 단계를 따르세요:

프로젝트 폴더를 엽니다. 디렉토리 구조는 다음과 같습니다:

├── css
│   └── index.css
├── index.html
└── js
    ├── data.json
    ├── axios.min.js
    ├── util.js
    └── index.js

여기서:

  • css/index.css는 CSS 스타일 파일입니다.
  • index.html은 메인 페이지입니다.
  • js/data.json은 데이터를 저장하는 JSON 파일입니다.
  • js/axios.min.js는 axios 파일입니다.
  • js/index.js는 완성해야 할 파일입니다.
  • js/util.js는 유틸리티 함수를 저장하는 파일입니다.

WebIDE 의 오른쪽 하단 모서리에 있는 Go Live 버튼을 클릭하여 프로젝트를 실행합니다.

다음으로, VM 상단의 "Web 8080"을 열고 수동으로 새로 고쳐 페이지를 확인합니다.

Initial Effect
✨ 솔루션 확인 및 연습

ajax 함수 구현

이 단계에서는 데이터 요청을 처리하기 위해 js/index.js 파일에서 ajax 함수를 구현합니다.

  1. js/index.js 파일을 엽니다.
  2. ajax 함수를 찾아 구현을 완료합니다.
  3. ajax 함수는 함수 인수를 기반으로 현재 페이지의 데이터와 총 페이지 수를 검색하고 반환해야 합니다.
  4. 제공된 Axios 라이브러리를 사용하여 ./js/data.json 파일에 HTTP 요청을 보낼 수 있습니다.

완성된 ajax 함수는 다음과 같습니다:

async function ajax({
  url,
  method = "get",
  data,
  query: { currentPage, pageSize }
}) {
  // TODO: Get the data of the current page according to the function parameters `query` object `currentPage, pageSize`.
  let result = {
    data: [],
    total: 0
  };

  let resData = [];
  let res = await axios[method](url, data);
  if (res.status === 200) {
    resData = res.data.data;
    result.total = res.data.total;
  }
  result.data = resData.slice(
    (currentPage - 1) * pageSize,
    currentPage * pageSize
  );

  return result;
}
✨ 솔루션 확인 및 연습

initEvents 함수 구현

이 단계에서는 페이지네이션 컴포넌트의 버튼에 이벤트를 바인딩하는 initEvents 함수를 js/index.js 파일에 구현합니다.

  1. js/index.js 파일을 엽니다.
  2. initEvents 함수를 찾아 구현을 완료합니다.
  3. "<" 버튼을 클릭하면 this.currentPage 값이 1 씩 감소하며, 최소값은 1 입니다.
  4. ">" 버튼을 클릭하면 this.currentPage 값이 1 씩 증가하며, 최대값은 this.totalPages입니다.
  5. this.currentPage 값이 변경되면 페이지의 페이지네이션 컴포넌트가 그에 따라 업데이트되어야 합니다.

완성된 initEvents 함수는 다음과 같습니다:

initEvents() {
    this.root.querySelector("#btn-prev").addEventListener("click", () => {
      // TODO: Click event for the "<" button, this.currentPage - 1 when clicked.
      if (this.currentPage > 1) {
        this.currentPage--;
        this.initPagination();
      }
    });
    this.root.querySelector("#btn-next").addEventListener("click", () => {
      // TODO: Click event for the ">" button, this.currentPage + 1 when clicked.
      if (this.currentPage < this.totalPages) {
        this.currentPage++;
        this.initPagination();
      }
    });
    this.root.querySelector(".pager").addEventListener("click", (e) => {
      if (e.target.nodeName.toLowerCase() === "li") {
        if (this.currentPage === e.target.innerText) return;
        if (e.target.classList.contains("more")) return;
        this.currentPage = Number(e.target.innerText);
      }
      this.initPagination();
    });
  }
✨ 솔루션 확인 및 연습

createPaginationIndexArr 함수 구현

이 단계에서는 특정 규칙에 따라 함수 인수를 기반으로 페이지네이션 배열 (indexArr) 을 생성하는 createPaginationIndexArr 함수를 js/util.js 파일에 구현합니다.

  1. js/util.js 파일을 엽니다.

  2. createPaginationIndexArr 함수를 찾아 구현을 완료합니다.

  3. 이 함수는 전달된 매개변수 currentPage, totalPages, pagerCount를 기반으로 페이지네이션 배열 (indexArr) 을 생성해야 합니다.

  4. 페이지네이션 배열을 생성하기 위한 규칙은 다음과 같습니다.

    • 특수한 경우: totalPages <= pagerCount
    • 일반적인 경우: totalPages > pagerCount
  5. 생성된 indexArr는 챌린지 설명에 제공된 예시를 따라야 합니다.

완성된 createPaginationIndexArr 함수는 다음과 같습니다:

const createPaginationIndexArr = (currentPage, totalPages, pagerCount) => {
  let indexArr = [];
  // TODO: Generate paging array based on passed parameters indexArr.
  indexArr[0] = 1;
  if (totalPages <= pagerCount) {
    for (let i = 1; i < totalPages; i++) {
      indexArr.push(i + 1);
    }
  } else {
    indexArr[pagerCount - 1] = totalPages;
    if (currentPage <= pagerCount - 2) {
      for (let i = 1; i < pagerCount - 1; i++) {
        indexArr[i] = i + 1;
      }
    } else if (currentPage <= totalPages - pagerCount + 2) {
      let j = 1;
      for (
        let i = -Math.ceil((pagerCount - 3) / 2);
        i <= Math.floor((pagerCount - 3) / 2);
        i++
      ) {
        indexArr[j++] = currentPage + i;
      }
    } else {
      let j = 1;
      for (let i = totalPages - pagerCount + 2; i < totalPages; i++) {
        indexArr[j++] = i;
      }
    }
  }

  return indexArr;
};
✨ 솔루션 확인 및 연습

renderPagination 함수 구현

이 단계에서는 indexArr 배열을 기반으로 페이지네이션 컴포넌트의 문자열 템플릿 template을 생성하는 renderPagination 함수를 js/index.js 파일에 구현합니다.

  1. js/index.js 파일을 엽니다.
  2. renderPagination 함수를 찾아 구현을 완료합니다.
  3. 이 함수는 챌린지 설명에 설명된 규칙에 따라 indexArr 배열을 기반으로 페이지네이션 컴포넌트의 문자열 템플릿 template을 생성해야 합니다.
  4. 생성된 templatethis.root.innerHTML을 사용하여 페이지네이션 컴포넌트의 HTML 구조에 삽입되어야 합니다.

완성된 renderPagination 함수는 다음과 같습니다:

renderPagination(indexArr) {
  let template = "";
  // TODO: Generates a string template template for the paging component based on the indexArr array.
  template = indexArr.reduce((prev, next, index) => {
    if (indexArr[index] - indexArr[index - 1] > 1) {
      prev += `<li class="number more">...</li>`;
      prev += `<li class="number ${
        this.currentPage == next ? "active" : ""
      }">${next}</li>`;
    } else {
      prev += `<li class="number ${
        this.currentPage == next ? "active" : ""
      }">${next}</li>`;
    }
    return prev;
  }, "");

  this.root.innerHTML = `
      <div class="pagination">
          <div class="btn btn-left" id="btn-prev">&lt;</div>
          <ul class="pager">${template} </ul>
          <div class="btn btn-right" id="btn-next">&gt;</div>
      </div>`;
}
✨ 솔루션 확인 및 연습

페이징 컴포넌트 테스트

이 단계에서는 페이지네이션 컴포넌트의 최종 결과를 테스트합니다.

  1. js/index.jsjs/util.js 파일을 저장합니다.
  2. 브라우저에서 웹 페이지를 새로 고칩니다.
  3. 페이지 효과를 확인합니다.

축하합니다! 페이지네이션 컴포넌트의 구현을 완료했습니다. 최종 페이지 효과는 다음과 같아야 합니다.

Image Description
✨ 솔루션 확인 및 연습

요약

축하합니다! 이 프로젝트를 완료했습니다. LabEx 에서 더 많은 랩을 연습하여 실력을 향상시킬 수 있습니다.