반응형
부모 컴포넌트
<div id="main">
<!-- 코드 생략... -->
<!--페이지네이션 컴포넌트-->
<!--
props로 자식 컴포넌트로 페이지네이션 관련 parameter 5개 전달하고
자식 컴포넌트에서 @update:current-page로 데이터(page) 전달 받음
-->
<paging-component :current-page="currentPage" :first-page="firstPage" :last-page="lastPage" :start-idx="startIdx" :end-idx="endIdx" @update:current-page="onUpdateCurrentPage"></paging-component>
</div>
<script layout:fragment="script" th:inline="javascript" type="text/javascript">
new Vue({
//element id
el: '#main',
//vue에서 관리할 데이터
data: {
items: [], // 데이터 목록
currentPage: 1, //현재 페이지
firstPage: 0, //첫번 째 페이지
lastPage: 0, //마지막 페이지
startIdx: 0, //첫번 째 페이지 번호
endIdx: 0, //마지막 페이지 번호
empNm: '', //사원명
},
//data를 기반으로 변경할 속성(data의 변경 감지)
computed: {
//변경된 데이터
displayedItems() {
return this.items;
},
},
//vue 컴포넌트 화면에 렌더링 된 직후 실행(컴포넌트의 템플릿이 DOM에 추가/화면에 표시된 직후)
mounted() {
//데이터 조회
this.fetchData();
},
methods: {
//데이터 조회
fetchData() {
const url = '/api/board';
//2번 째 parameter(queryString)
const params = { params:
{ currentPage: this.currentPage,
empNm: this.empNm
}
};
//ajax 호출
axios.get(url, params)
.then(function(response) {
this.items = response.data.list;
this.firstPage = response.data.paging.firstPage;
this.lastPage = response.data.paging.lastPage;
this.startIdx = response.data.paging.firstPageNo;
this.endIdx = response.data.paging.lastPageNo;
}.bind(this))
.catch(function(error) {
// 에러 처리
console.log(error);
});
},
// 페이지 이동 이벤트 시 수행(자식 컴포넌트에서 전달받은 page)
onUpdateCurrentPage(page) {
this.currentPage = page;
this.fetchData(); // fetchData() 메서드 실행
},
//검색
search() {
this.currentPage = 1;
this.fetchData();
},
},
});
자식컴포넌트
// 페이징 관련 컴포넌트
// 부모 컴포넌트에게 props로 데이터 전달 받아서 페이징 시작~종료인덱스 세팅 후 페이지네이션 처리
Vue.component('paging-component', {
props: ['currentPage', 'firstPage','lastPage', 'startIdx', 'endIdx'],
computed: {
//페이징 개수 세팅(시작인덱스, 종료인덱스를 받아서 동적으로 array 세팅)
pagedArray() {
const pagedArr = [];
for (let i = this.startIdx; i <= this.endIdx; i++) {
pagedArr.push(i);
}
return pagedArr;
},
},
methods: {
movePage(page) {
//이벤트 발생(부모 컴포넌트에게 데이터 전달)
this.$emit('update:current-page', page);
},
},
//페이지네이션 템플릿
template: `
<div class="paging tbl-paging">
<ul class='pagination'>
<!--first-->
<li class='paginate_button page-item first'>
<button
type='button'
class='page-link'
:style="{ cursor: currentPage !== firstPage ? 'pointer' : 'default' }"
:disabled="currentPage === firstPage"
@click="movePage(firstPage)"
>
<span class='hidden'>첫 페이지</span>
</button>
</li>
<!--prev-->
<li class='paginate_button page-item prev'>
<button
type='button'
class='page-link'
:style="{ cursor: currentPage !== firstPage ? 'pointer' : 'default' }"
:disabled="currentPage === firstPage"
@click="movePage(currentPage - 1)"
>
<span class='hidden'>이전 페이지</span>
</button>
</li>
<!--① ~ ⑩-->
<li
class='paginate_button page-item'
v-for="(page, index) in pagedArray"
:key="index"
:class="{ 'active': currentPage === page }"
@click="movePage(page)"
>
<button type='button' class='page-link' style='cursor: pointer;'>
{{ page }}
</button>
</li>
<!--next-->
<li class='paginate_button page-item next'>
<button
type='button'
:disabled="currentPage === lastPage"
class='page-link'
:style="{ cursor: currentPage !== lastPage ? 'pointer' : 'default' }"
@click="movePage(currentPage + 1)"
>
<span class='hidden'>다음 페이지</span>
</button>
</li>
<!--last-->
<li class='paginate_button page-item last'>
<button
type='button'
:disabled="currentPage === lastPage"
class='page-link'
:style="{ cursor: currentPage !== lastPage ? 'pointer' : 'default' }"
@click="movePage(last)"
>
<span class='hidden'>마지막 페이지</span>
</button>
</li>
</ul>
</div>
`,
});
반응형
'IT > development' 카테고리의 다른 글
[Vue.js] 기존 thymeleaf에 Vue.js 적용하는 방법 (2) | 2023.08.10 |
---|---|
[Vue.js] 콜백 함수에서 this 사용 시 유의점 (2) | 2023.08.10 |
[Vue.js] modal창 데이터 바인딩 안될 때 (2) | 2023.08.06 |
[Vue.js] vue.js의 렌더링 방식과 기존 방식의 차이점(feat. ajax) (8) | 2023.07.30 |
[Vue.js] watch vs computed(데이터 변화 감지) (0) | 2023.07.30 |