Sharryhong's Front-End
  • About Sharryhong's Front-End Blog.
  • Front-End Dev
    • Flutter
      • API Key 안전하게 숨기기. Cloudflare Workers!
      • Web CORS 에러
    • Vue.js
      • usePagination - composition api (vue2)
      • Pagination Component
      • Vue Image Skeleton
      • Sort an Array of Objects by Boolean property
      • Dynamic Components
      • LoadingBar Component
      • composition-api 사용하여 menu 의 outside click 시 close
      • vue+TypeScript
      • Vue.js 개발자를 위한 VS Code
      • Vue3 Chrome Extension
      • input file 선택된 파일 명 reset하기
      • element 내부 scroll 될 때, ScrollTop 값에 따라 div를 보이게, 안보이게 제어하기
      • 진입한 url path에 맞게 메서드 실행
    • React
      • 절대경로(absolute path) 설정, jsx파일로 이동 설정
      • useContext rerender issue
      • Firebase v9 Auth with React
      • Firebase v9 Realtime Database with React
      • React Star Rating (별점 표시)
      • React App deploying (배포)
    • Next.js
      • CSR, SSR, Next.js
    • API Mocking
      • Vue 에서 msw 적용하기
    • Storybook
      • styled-component theme.ts가 storybook엔 적용안되는 이슈
      • storybook에서 alias path 안되는 이슈
      • storybook에 Global Style 적용하기
  • etc
    • brew update
    • npm upgrade (mac)
  • DEV BETTER
    • Clean Code
      • Clean Code JavaScript 강의
        • Variables - 변수 다루기
        • Boundary - 경계 다루기
        • Conditional - 분기 다루기
        • Array - 배열 다루기
      • Tip. 클린 코드를 위한 5가지 팁
      • Tip. 코딩 잘하는 팁 3가지
    • 웹 성능 최적화 (performance)
      • performance 강의
        • loading, rendering performance
        • Tools
        • Image size optimization
        • bottleneck (병목) code 탐색
Powered by GitBook
On this page
  • 이슈
  • 해결 코드

Was this helpful?

  1. Front-End Dev
  2. Vue.js

Pagination Component

2022-08-04

PrevioususePagination - composition api (vue2)NextVue Image Skeleton

Last updated 2 years ago

Was this helpful?

이슈

  • 기존 사용중이던 Pagination 컴포넌트 내부 코드의 복잡함

  • 스크립트가 여러 파일에 흩어져 있어서 유지보수의 어려움

참고 자료

  • startPage, endPage 구하는 식만 참고하였고, pagingList의 경우에는 Array.from 메소드로 리팩토링하였습니다.

해결 코드

Pagination.vue

<template>
  <div>
    <ol>
      <li>
        <Button
          :disabled="pageOptions.first"
          @click="onClick(1)"
        >
          처음 페이지
        </Button>
      </li>
      <li>
        <Button
          :disabled="pageOptions.first"
          @click="onClick(pageOptions.page - 1)"
        >
          이전 페이지
        </Button>
      </li>
      <li v-for="page in pagingList" :key="page">
        <button
          type="button"
          :class="['btn_page_number', { selected: pageOptions.page === page }]"
          @click="onClick(page)"
        >
          {{ page }}
        </button>
      </li>
      <li>
        <Button
          :disabled="pageOptions.last"
          @click="onClick(pageOptions.page + 1)"
        >
          다음 페이지
        </Button>
      </li>
      <li>
        <Button
          :disabled="pageOptions.last"
          @click="onClick(pageOptions.totalPages)"
        >
          마지막 페이지
        </Button>
      </li>
    </ol>
  </div>
</template>

<script lang="ts">
import Vue from "vue";

export default Vue.extend({
  props: {
    pageOptions: {
      type: Object,
    },
    // 화면에 출력할 페이지 갯수
    totalVisible: {
      type: Number,
      default: 10,
    },
  },
  computed: {
    // 페이지 시작 번호
    startPage() {
      return (
        Math.trunc((this.pageOptions.page - 1) / this.totalVisible) *
          this.totalVisible +
        1
      );
    },
    // 페이지 끝 번호
    endPage() {
      let end = this.startPage + this.totalVisible - 1;
      return end < this.pageOptions.totalPages
        ? end
        : this.pageOptions.totalPages;
    },
    // 화면에 표시할 페이지 리스트 
    pagingList() {
      return this.rangeNumberToArray(this.startPage, this.endPage);
    },
  },
  methods: {
    onClick(page: number) {
      this.$emit("click", page);
    },
    // start, end 숫자로 배열 만드는 기능 
    rangeNumberToArray(start: number, end: number) {
      return Array.from({ length: end - start + 1 }, (_, i) => start + i);
    },
  },
});
</script>

<style scoped lang="scss">
...
</style>

사용 예

<template>
  ...
  <Pagination :pageOptions="pageOptions" @click="onClickPage" /> 
</template>

<script lang="ts">
  export default Vue.extend({
    data: () => ({
      pageOptions: {
      page: 1,
      size: 10,
      totalElements: 0,
      totalPages: 0,
      first: false,
      last: false,
    },
    ...

    methods: {
      onClickPage(page: number) {
        this.pageOptions.page = page;
        this.fetchNotice();
      },
            
https://19-97.tistory.com/130