본문 바로가기
Vue.js

[Vue.js] 08. use v-data-table

by 청양호박이 2021. 2. 10.

이번에는 table형태로 표현이 가능한 data를 vuetify를 통해서 구현해 보도록 하겠습니다. 기존에 AT Project를 통해서 구현했던, corp_info table을 Spring Boot에 구현한 Rest API를 통해서 가져오고 그 결과를 vue.js로 렌더링 하는 것 입니다. 일단 구현했을때 그 결과 화면을 보고... 어떻게 구현을 해야할지 고민해 보겠습니다.

 

아마 아래 화면은 대다수의 application이 구현하고 제공하는 양식입니다. 

 

API를 통해서 가져온 데이터를 list로 이쁘게 뿌려주고... 데이터가 음청 많을경우 아래처럼 pagination되어 해당 부분만 보여주도록 되어있습니다. 그리고 다음 page를 보려면 next버튼 혹은 원하는 page번호를 선택하면 해당 페이지의 데이터를 보여주는 방식이죠.

 

현재 위의 예시에는 아래와 같은 기능이 적용되어있습니다. 

 

  • API를 통해서 가져온 data를 list화 하여 화면에 표출하는 기능
  • list가 너무 길 경우 page단위로 나누어서 pagination 하여 화면에 표출하는 기능
  • search를 통해서 원하는 데이터만 보여주는 기능

 

그렇다면 vuetify를 통해서 어떻게 구현하는지 알아보겠습니다. 우선 vuetify에 들어가서 UI Components부분을 살펴봅니다. 그럼 table에 대한 내용이 있는데... 그 부분을 쭉 살펴보고 내가 구현해 보고 싶은 항목들을 찾아봅니다.

 

UI Components > Tables > Data tables 선택

 

이 중에서 제가 적용할 항목은 아래와 같습니다.

 

(1) v-data-table (2) Loading (3) Search (4) Exteral pagination

 

vuetify의 장점은 내가 원하는 항목을 쭉 찾아서 코드에서 쭉 합쳐주면 되는 방식입니다. 각 부분별로 내용을 확인해 보고 전체 구현 소스는 마지막에 살펴보도록 하겠습니다.

 

[v-data-table]

        <v-data-table
          :headers="headers"
          :items="items"
          :items-per-page="itemsPerPage"
          hide-default-footer
          class="elevation-1"></v-data-table>
          
=============================================================   
data() {
    return {
      page: 1,
      pageCount: 0,
      itemsPerPage: 10,
      headers: [
        { text: '회사명', align: 'center', sortable: false, value: 'corpName' },
        { text: '회사코드', align: 'center', sortable: false, value: 'corpCode' },
        { text: '종목코드', align: 'center', sortable: false, value: 'stockCode' },
        { text: '수정일자', align: 'center', sortable: false, value: 'modifyDate' },
      ],
      items: [],
    };
  },  

v-data-table에서는 기본적으로 3가지의 prop를 사용합니다.

 

    :headers = 필드명을 지정하는 prop로 text, align, sortable, value로 구분합니다. value의 경우는 향후 data를 적용 시

                  데이터 내 DTO와 일치시키면 됩니다.

    :items = API로 받아온 결과 list가 저장되는 장소입니다. 

    :items-per-page = 한 page에서 보여줄 list의 개 수 입니다. 

 

해당 항목별로... data( ) 에서 값을 지정해 주면 됩니다.

 

[Loading]

        <v-data-table
          :headers="headers"
          :items="items"
          :loading="loading"
          loading-text="Loading... Please wait"
          :items-per-page="itemsPerPage"
          hide-default-footer
          class="elevation-1"></v-data-table>
          
=============================================================   
data() {
    return {
      page: 1,
      pageCount: 0,
      itemsPerPage: 10,
      loading: true,
      headers: [
        { text: '회사명', align: 'center', sortable: false, value: 'corpName' },
        { text: '회사코드', align: 'center', sortable: false, value: 'corpCode' },
        { text: '종목코드', align: 'center', sortable: false, value: 'stockCode' },
        { text: '수정일자', align: 'center', sortable: false, value: 'modifyDate' },
      ],
      items: [],
    };
  },  

loading을 위해서는 v-data-table에 2가지 prop이 추가됩니다. 

 

    :loading = loading에 대한 progress bar를 보여주는 정의를 하는 부분입니다. data( )의 loading값을 boolean으로 

                  지정하여 보여주고/안보여주고를 조절합니다.

    loading-text = items에 아직 데이터가 들어오지 않은 경우, 보여주는 default text입니다. 현재 data( )는 items를 [ ]

                        비어있는 list로 지정하기 때문에 처음에는 항상 loading-text를 보여주게 됩니다.

 

[Search]

      <v-card>
        <v-card-title>
          CorpInfo
          <v-spacer></v-spacer>
          <v-text-field
            v-model="search"
            append-icon="mdi-magnify"
            label="Search"
            single-line
            hide-details></v-text-field>
        </v-card-title>
        <v-data-table
          :headers="headers"
          :items="items"
          :search="search"
          :loading="loading"
          loading-text="Loading... Please wait"
          :items-per-page="itemsPerPage"
          hide-default-footer
          class="elevation-1"></v-data-table>
          
=============================================================   
data() {
    return {
      page: 1,
      pageCount: 0,
      itemsPerPage: 10,
      search: '',
      loading: false,
      headers: [
        { text: '회사명', align: 'center', sortable: false, value: 'corpName' },
        { text: '회사코드', align: 'center', sortable: false, value: 'corpCode' },
        { text: '종목코드', align: 'center', sortable: false, value: 'stockCode' },
        { text: '수정일자', align: 'center', sortable: false, value: 'modifyDate' },
      ],
      items: [],
    };
  },  

Search를 위해서는 text영역을 추가해야 하기 때문에 관련된 v-text-field를 추가해 줍니다. v-text-field에는 주의해야할 prop가 있는데... v-model입니다. 해당 prop는 v-text-field에서 text를 입력하면 해당 변수로 그 값을 전달해 주는 prop 입니다. 

 

따라서, 입력값을 넣어주는 data( )내 search변수에 저장이 되는 것이지요~ 그 결과는 v-data-table의 :search prop에 전달이 되게 됩니다. 

 

    :search = API를 통해서 전달된 전체 항목 중 원하는 항목을 like 검색을 통해서 대상 list만 표시하도록 해주는 검색어

                를 지정하는 변수입니다.

 

[External pagination]

      <v-card>
        <v-card-title>
          CorpInfo
          <v-spacer></v-spacer>
          <v-text-field
            v-model="search"
            append-icon="mdi-magnify"
            label="Search"
            single-line
            hide-details></v-text-field>
        </v-card-title>
        <v-data-table
          :headers="headers"
          :items="items"
          :search="search"
          :loading="loading"
          loading-text="Loading... Please wait"
          :page.sync="page"
          :items-per-page="itemsPerPage"
          hide-default-footer
          class="elevation-1"
          @page-count="pageCount = $event"></v-data-table>
        <div class="text-center pt-2">
          <v-pagination
            v-model="page"
            :length="pageCount"
            :total-visible="totalVisible"
            next-icon="mdi-menu-right"
            prev-icon="mdi-menu-left"></v-pagination>
        </div>
      </v-card>
=================================================================================
  data() {
    return {
      text: 'Welcome to AyoteraLab',
      page: 1,
      pageCount: 0,
      itemsPerPage: 10,
      totalVisible: 10,
      search: '',
      loading: true,
      headers: [
        { text: '회사명', align: 'center', sortable: false, value: 'corpName' },
        { text: '회사코드', align: 'center', sortable: false, value: 'corpCode' },
        { text: '종목코드', align: 'center', sortable: false, value: 'stockCode' },
        { text: '수정일자', align: 'center', sortable: false, value: 'modifyDate' },
      ],
      items: [],
    };
  },

pagination을 위해서는 추가로 UI components가 필요합니다. v-pagination이 그것입니다. pagination을 위한 다양한 prop가 존재합니다.

 

  v-data-table

    :page.sync = 원하는 page를 선택했을때, 자동적으로 대상 page로 전환이 되려면 추가해 줍니다.

    @page-count = 전체 페이지의 count를 동적으로 할당해 줍니다.

  v-pagination

    :length = pagination에 대상이되는(표시기준이 아님) 전체 page의 count를 알려줍니다.

    :total-visible = pagination에 표시할 page의 개수를 지정합니다. 해당 개수를 초과할 경우 ...... 으로 표시됩니다.

    next-icon = 다음 페이지로 이동하기 위한 icon을 지정합니다.

    prev-icon = 이전 페이지로 이동하기 위하 icon을 지정합니다.

 

이렇게 구현이 완료되었습니다. 아참!! axios에서 API를 통해서 데이터를 가져왔을때, loading에 대한 progress bar를 해제 시키기 위한 값을 변경해야겠네요.

  methods: {
    getCorpInfo() {
      const url = '/corp/select';
      axios.get(url,
      ).then((res) => {
        console.log(res.data);
        this.items = res.data;
        this.loading = false;
      });
    },
  },

별 어려움 없이... this.loading = false로 변경해 주면 됩니다~~~

 

- Ayotera Lab -

댓글