본문 바로가기
개발이야기/Vue

[Vue] 사진첩 게시판

by dev.josh 2022. 11. 17.
반응형

목차

1. 환경

2. 반응형 화면

3. 기능

4. 프로젝트 구조

5. 컴포넌트 구조

6. 주요 메서드

7. 전체소스

 

1.  환경

  • node v16.15.0 or v18.12.0
  • vue2
  • vue/cli 5.0.8

 

2.  반응형 화면

 

3.  기능

   

 

 

    1. 사진 상세보기 (모달창 활성화)

    2. 페이징 처리

    3. 요청 게시물 개수 설정 (설정값 로컬스토리지에 저장)

    4. 상세페이지 닫기( 모달창 비활성화)

 

 

 

 

 

 

 

 

4.  프로젝트 구조

 

 

 

 

src

  ⌞ api

     ⌞ ContactsAPI.ts : API 호출 및 데이터 반환. 

  ⌞ components

     ⌞ Layout

         ⌞Loading.vue : 로딩 애니메이션

     ⌞ Item.vue : 게시물1개에 대한 컴포넌트

     ⌞ List.vue : 게시물의 목록 컴포넌트

     ⌞ Modal.vue : 모달창 컴포넌트

     ⌞ Paginations.vue : 페이징 컴포넌트

  ⌞ store

     ⌞ mutations.ts : vuex 데이터 변이에 해당되는 파일

     ⌞ state.ts : vuex 인터페이스와 변수가 선언되어있는 파일

     ⌞ actions.ts : vuex 동작에 해당되는 파일

 

 

 

 

 

 

 

 

 

 

 

5.  컴포넌트 구조


6.  주요 메서드

목록 조회 동작은 List컴포넌트에 자식으로 존재하는 Paginations컴포넌트에서만 가능하도록 하였다.

Paginations컴포넌트에서 페이징을 동작할때 부모 List컴포넌트의 getPhotoList 메서드를 호출하는 방식으로 진행 하였다.

 

목록은 List컴포넌트에서 Item컴포넌트를 반복해서 그려준다. (List.vue)

<div class="container">
  <Item
    v-for="item in resultList"
    :key="item.id"
    :id="item.id"
    :download_url="item.download_url"
    :wSize="200"
  ></Item>
</div>

 

API요청시 로딩과 에러 관련 처리 (actions.ts)

  async getPhotoList(store: any, payload: any): Promise<any> {
    const page = payload.page;
    const limit = store.state.options.limit;
    await store.commit("isLoadingSet", true);
    try {
      const response = await ContactAPI.getPhotoList(page, limit);
      return response;
    } catch (error) {
      await store.commit("isErrorSet", true);
      return error;
    } finally {
      await store.commit("isLoadingSet", false);
    }
  },

 

renderPagination함수 에서는 전체 게시물 개수와 현재 페이지를 받아서 페이징 목록을 그려준다. (Paginations.vue)

(전체 게시물 개수는 1000개로 고정함)

  <ul>
    <li v-if="prev > 0" @click="prePage()">
      <span>〈</span>
    </li>
    <li
      v-for="(page, index) in pageList"
      :key="index"
      :class="{ active: page === currentPage }"
      @click="movePage(page)"
    >
      <span>{{ page }}</span>
    </li>
    <li v-if="last < totalPage" @click="nextPage()"><span>〉</span></li>
  </ul>

 

  renderPagination(totalCount: number, currentPage: number): void {
    if (totalCount <= this.pageGroupCount) return;
    this.totalPage = Math.ceil(totalCount / this.limit);
    let pageGroup = Math.ceil(currentPage / this.pageGroupCount);
    this.currentPage = currentPage;
    this.last = pageGroup * this.pageGroupCount;
    if (this.last > this.totalPage) this.last = this.totalPage;
    this.first =
      this.last - (this.pageGroupCount - 1) <= 0
        ? 1
        : this.last - (this.pageGroupCount - 1);
    this.next = this.last + 1;
    this.prev = this.first - 1;
    this.pageList = [];
    for (let index = this.first; index <= this.last; index++) {
      this.pageList.push(index);
    }
  }

 

7. 전체 소스

https://github.com/Jo-App/vue2_photo_board

 

GitHub - Jo-App/vue2_photo_board

Contribute to Jo-App/vue2_photo_board development by creating an account on GitHub.

github.com

 

 

반응형