Vue, Pagination, Vuetify table을 이용한 페이징 네이션

2021. 2. 24. 18:49Vue

vuex, axios, vuetify를 이용한 페이징 네이션

 

axiox를 이용하여 백엔드에서 데이터를 받아온다.

연결 방법은 crispypotato.tistory.com/21 여기!

 

vuetify data-table : vuetifyjs.com/en/components/data-tables/#header

 

Data table component

The data table component is used for displaying tabular data in a way that is easy for users to scan. It includes so...

vuetifyjs.com

 

  • template
<template>
  <v-container>
    <v-data-table
      :headers="headers"
      :items="items"
      :server-items-length="postLenth"
      :options.sync="options"
      :items-per-page="2"
      :disable-items-per-page="true"
      :footer-props="footerProps"
      class="elevation-1"
      :loading="loading"
    />
  </v-container>
</template>

 

 

  • script
<script>
import { mapState } from 'vuex'
export default {
  data () {
    return {
      loading: true,
      studentModal: false,
      postLenth: 0,
      page: 0,
      options: {},
      countPost: 0,
      items: [],
      footerProps: { 'items-per-page-options': [2, -1] },
      headers:
      [
        {
          text: '이름',
          align: 'start',
          sortable: false,
          value: 'name'
        },
        { text: '랭킹', value: 'rank' },
        { text: '학년', value: 'grade' },
        { text: '반', value: 'class' }
      ]
    }
  },
  computed: {
    ...mapState(['items'])
  },
  watch: {
    options: {
      handler () {
        this.api()
      },
      deep: true
    }
  },
  methods: {
    async api () {
      this.loading = true
      const data = await this.paging(this.options)
      this.items = data.items
      this.postLenth = data.itemCount
      this.loading = false
    },
    async paging () {
      const { sortBy, sortDesc, page, itemsPerPage } = this.options
      this.countPost = itemsPerPage
      if (itemsPerPage === -1) {
        await this.$store.dispatch('USER_LIST', { year: this.$store.state.year, page: page, postCount: 'all', totalPost: this.$store.state.page.totalPost, expiry: this.$store.state.study })
      } else if (this.$store.state.items.length === this.$store.state.page.totalPost) {
        console.log()
      } else if (page > this.$store.state.page.currentPage || !this.$store.state.page.currentPage) {
        await this.$store.dispatch('USER_LIST', { year: this.$store.state.year, page: page, postCount: itemsPerPage, expiry: this.$store.state.study })
      }

      let items = this.$store.state.items
      const itemCount = this.$store.state.page.totalPost

      if (sortBy.length === 1 && sortDesc.length === 1) {
        items = items.sort((a, b) => {
          const sortA = a[sortBy[0]]
          const sortB = b[sortBy[0]]

          if (sortDesc[0]) {
            if (sortA < sortB) return 1
            if (sortA > sortB) return -1
            return 0
          } else {
            if (sortA < sortB) return -1
            if (sortA > sortB) return 1
            return 0
          }
        })
      }

      if (itemsPerPage > 0) {
        items = items.slice((page - 1) * itemsPerPage, page * itemsPerPage)
      }
      return { items, itemCount, itemsPerPage }
    }
  }

}
</script>

설명 => 

  1. footer-props가 페이징네이션을 변경
  2. watch에 deep옵션이 있어서 배열 내부의 변경을 검사한다.
  3. api() 실행 안에 있는 paging()를 실행
  4. paging() 페이징 처리를 한 후 액션을 통해 백에 데이터를 요청

* footeritems-per-page-options : 페이징 처리할 데이터 숫자 지정, -1일경우 all   

  • 결과

 

 

출처 : dev.to/instantwebtoolsnet/datatables-with-vuejs-vuetify-pagination-rest-api-3jji

728x90
반응형