Develop/Vue

[nuxt.js] 페이지 네이션, 스크롤 페이징

김니은  2020. 4. 5. 21:09
반응형

이번 글은 node.js를 통해 데이터를 가져온 후, pagination과 infinite-loading 기법을 적용하는 방법을 정리해 보았습니다.

페이지네이션 (Pagination)

 

위 그림과 같이 페이지마다 5개의 목록을 가져오도록 하겠습니다.

 

...
  data () {
    return {
      commentlist : [],
      curpagenum : 1,
      datapage : 5
    }
  },

  methods: {
    ...
    async getCommentlist () {
      await axios.get(' [ 데이터 가져올 api 주소 ] '+ this.$route.params.id).then(
        (res) => {
          this.commentlist = res.data.data // 데이터 배열 저장
        },
        (err) => {
          console.log(err)
        }
      )
    }
  },
  computed: {
    startOffset() {
      return ((this.curpagenum - 1) * this.datapage);
    },
    endOffset() {
      return (this.startOffset + this.datapage);
    },
    numofpage() {
        return Math.ceil(this.commentlist.length / this.datapage);
    },
    calData() {
      return this.commentlist.slice(this.startOffset, this.endOffset);
    }
  },
  mounted () {
    ...
    this.getCommentlist()
  }
}

 

위는 nuxt의 script 주소입니다.

페이지에 글 5개씩 출력하도록 하였습니다.

 

<h2>리뷰 테스트</h2>
  <div v-for="(item, index) in calData">
    <div v-if="index != 0"></div>
    <h4>{{ item.[ 테이블 필드 ] }}</h4>
  </div>
  <v-pagination :length= "numofpage" v-model="curpagenum"> </v-pagination>
</div>

 

html에 해당 내용을 입력하시면 해당 테이블의 정보를 출력하게 됩니다.


스크롤 페이징 (infinite-loading)

 

 

스크롤페이징 구현 화면 *출처:공식문서

페이스 북처럼 아래로 스크롤을 내리면 계속 해당 정보를 출력해주는 기능입니다.

먼저 npm 모듈을 설치해줍시다.

 

 

npm install vue-infinite-loading -s

 

모듈 설치 후 소스를 적어봅시다.

 

import axios from 'axios'
import InfiniteLoading from 'vue-infinite-loading'
...

export default {
  ...

  components: {
    InfiniteLoading
  },
  data () {
    return {
      limit: 5,
      list: [],
      busy: false,
      listItems: [],
      ...
    }
  },
  methods : {
    ...
    async getItem () {
      await axios.get('[ api 주소 ]').then(
        (res) => {
          this.listItems = res.data.data
        },
        (err) => {
          console.log(err)
        }
      )
    },
    async infiniteHandler ($state) {
      await setTimeout(() => {
        const temp = []
        if (this.busy === false) {
          for (let i = this.list.length + 1; i <= this.list.length + 5; i++) {
            temp.push(this.listItems[i])
            if (this.listItems.length - 1 === i) {
              this.busy = true
              break
            }
          }
        }
        if (this.busy === true) {
          $state.complete()
        }
        this.list = this.list.concat(temp)
        $state.loaded()
      }, 1000)
    }
  },
  mounted () {
    ...
    this.getItem()
    this.infiniteHandler()
  }
...

 

getItem 메서드를 통해 데이터를 가져온 후 infiniteHandler 메서드에서 이를 5개씩 잘라 스크롤을 내릴 때 마다 정보를 push해서 출력해줍니다.

제 느낌대로 만든거라.. 더 정리할 수 있을 것 같은데.. 아직은 생각이 안나네요..

 

<div v-for="item in list">
  {{ item }}
</div>
<infinite-loading @infinite="infiniteHandler"></infinite-loading>

 

html 부분에 해당 내용을 작성 후 출력해보았습니다.

 

...? 왠 오류지..

다른 사이트에서 링크를 타서 들어가면 정상적으로 되지만.. 바로 주소치고 들어가면 에러뜹니다.

ssr 오류라 하네요

고쳐줍시다.

  ...
  plugins: [
    '~/plugins/i18n.js',
    '~/plugins/axios.js',
    '~/plugins/infinite-load.js'
  ],
  ...

 

스크립트 쪽에 해당 소스를 추가해줍니다.

 

<no-ssr><infinite-loading @infinite="infiniteHandler"></infinite-loading></no-ssr>

 

no-ssr 태그를 추가해줍시다.

정보가 제대로 출력되네요!

모든 정보가 출력되면 아래에 해당 문구가 뜹니다.

css 아무거나 입혀보니 제대로 작동되는걸 확인할 수 있습니다.

반응형