brunch

You can make anything
by writing

C.S.Lewis

by 서환수 Jan 15. 2024

v-data-table 페이지 유지 방법

Vue.js로 개발을 하는데 디자인 역량이 부족하다 싶으면 적당한 UI 라이브러리를 잘 써야 그나마 볼 만한 인터페이스를 만들 수 있습니다. 그 때 쓸 수 있는 툴 가운데 하나가 Vuetify입니다.


Vuetify에서 표를 표현하고 싶을 때 많이 사용하는 게 v-data-table 컴포넌트인데요, 이 컴포넌트를 쓰다 보면 컴포넌트의 특정 행을 클릭해서 다른 라우트로 넘어갔다가 다시 원래 v-data-table 컴포넌트를 보여주는 라우트로 돌아오는 상황이 자주 생길 수 있습니다. (마치 게시판에서 게시물 목록에 있는 특정 게시물을 클릭해서 내용을 보고는 이전 페이지 아이콘을 클릭해서 게시물 목록으로 돌아오는 것처럼 말이죠.) 이 때 표의 원래 페이지로 돌아가는 게 자연스러운데, v-data-table의 기본 설정을 그대로 사용한다면 항상 첫 페이지로 되돌아가게 됩니다.


이 문제를 해결하기 위해서는 사용자가 특정 행을 클릭해서 다른 화면으로 넘어가기 전에 미리 페이지 정보를 어딘가에 저장해야 합니다. 이렇게 서로 다른 뷰로 넘어가더라도 상태를 유지할 때 쓸 수 있는 게 Pinia 저장소입니다. Pinia 저장소에 currentPage라는 이름으로 페이지 정보를 저장하도록 합시다.


다음과 같은 식으로 stores/dataTableStore.js라는 파일을 만들어 줍니다.


// stores/dataTableStore.js
import { defineStore } from 'pinia';

export const useDataTableStore = defineStore('dataTable', {
  state: () => ({
    currentPage: 1
  }),
  actions: {
    setCurrentPage(page) {
      this.currentPage = page;
    }
  }
});


그리고 뷰 라우터에서 


테이블을 보여주는 컴포넌트는 다음과 같은 식으로 구성하면 됩니다.


<template>
  <v-data-table
    :items="items"
    :page="page"
    :items-per-page="5"
    @update:page="updatePage"
  ></v-data-table>
</template>

<script>
import { useDataTableStore } from '@/stores/dataTableStore';
import { onMounted, ref, watch } from 'vue';
import { useRoute } from 'vue-router';

export default {
  setup() {
    const store = useDataTableStore();
    const page = ref(store.currentPage);
    const route = useRoute();

    const updatePage = (newPage) => {
      // 라우트가 활성화된 후에만 페이지 업데이트
      if (route.meta.isActivated) {
        page.value = newPage;
        store.setCurrentPage(newPage);
      }
    };

    onMounted(() => {
      // 라우트 활성화 플래그 설정
      route.meta.isActivated = true;
      page.value = store.currentPage;
    });

    return {
      items,
      page,
      updatePage
    };
  }
};
</script>


컴포넌트가 마운트될 때 매번 페이지를 업데이트하는 로직이 실행되면 이 컴포넌트에서 다른 컴포넌트로 갔다가 다시 이 컴포넌트로 돌아올 때 무조건 currentPage가 1로 초기화되는 문제가 생기기 때문에 이 문제를 해결하기 위해 route.meta.isActivated라는 플래그를 활용합니다. (onMounted 이벤트 처리부에서 route.meta.isActivated를 참으로 설정하고, 이 플래그가 활성화된 이후에만 페이지를 업데이트하는 거죠.)


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari