페이지네이션 및 조회수 카드에 추가, 검색 수정
This commit is contained in:
parent
5400dea491
commit
0fa34fe90c
@ -24,8 +24,11 @@
|
||||
<!-- 날짜 -->
|
||||
<div class="d-flex justify-content-between">
|
||||
<small class="text-muted">{{ formattedDate }}</small>
|
||||
<!-- 좋아요와 댓글 -->
|
||||
<!-- 조회수, 좋아요, 댓글 -->
|
||||
<div>
|
||||
<span class="text-muted me-3">
|
||||
<i class="fa-regular fa-eye"></i> {{ views || 0 }}
|
||||
</span>
|
||||
<span class="text-muted me-3">
|
||||
<i class="bx bx-like"></i> {{ likes || 0 }}
|
||||
</span>
|
||||
@ -66,6 +69,10 @@ const props = defineProps({
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
views: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
likes: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
:title="post.title"
|
||||
:content="post.content"
|
||||
:date="post.date"
|
||||
:views="post.views"
|
||||
:likes="post.likes"
|
||||
:comments="post.comments"
|
||||
/>
|
||||
|
||||
@ -1,35 +1,126 @@
|
||||
<template>
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination pagination-rounded justify-content-center">
|
||||
<!-- <li class="page-item first">
|
||||
<a class="page-link" href="javascript:void(0);"><i class="tf-icon bx bx-chevrons-left bx-sm"></i></a>
|
||||
</li> -->
|
||||
<!-- <li class="page-item prev">
|
||||
<a class="page-link" href="javascript:void(0);"><i class="tf-icon bx bx-chevron-left bx-sm"></i></a>
|
||||
</li> -->
|
||||
<li class="page-item active">
|
||||
<a class="page-link" href="javascript:void(0);">1</a>
|
||||
<!-- 첫 페이지 이동 -->
|
||||
<li
|
||||
class="page-item first"
|
||||
@click="emitPageChange(navigateFirstPage)"
|
||||
:class="{ disabled: isFirstPage }"
|
||||
>
|
||||
<a class="page-link" href="javascript:void(0);">
|
||||
<i class="tf-icon bx bx-chevrons-left bx-sm"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="javascript:void(0);">2</a>
|
||||
|
||||
<!-- 이전 페이지 이동 -->
|
||||
<li
|
||||
class="page-item prev"
|
||||
@click="emitPageChange(prePage)"
|
||||
:class="{ disabled: !hasPreviousPage }"
|
||||
>
|
||||
<a class="page-link" href="javascript:void(0);">
|
||||
<i class="tf-icon bx bx-chevron-left bx-sm"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="javascript:void(0);">3</a>
|
||||
|
||||
<!-- 페이지 번호들 -->
|
||||
<li
|
||||
v-for="page in navigatepageNums"
|
||||
:key="page"
|
||||
:class="['page-item', { active: page === currentPage }]"
|
||||
@click="emitPageChange(page)"
|
||||
>
|
||||
<a class="page-link" href="javascript:void(0);">{{ page }}</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="javascript:void(0);">4</a>
|
||||
|
||||
<!-- 다음 페이지 이동 -->
|
||||
<li
|
||||
class="page-item next"
|
||||
@click="emitPageChange(nextPage)"
|
||||
:class="{ disabled: !hasNextPage }"
|
||||
>
|
||||
<a class="page-link" href="javascript:void(0);">
|
||||
<i class="tf-icon bx bx-chevron-right bx-sm"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="javascript:void(0);">5</a>
|
||||
</li>
|
||||
<li class="page-item next">
|
||||
<a class="page-link" href="javascript:void(0);"><i class="tf-icon bx bx-chevron-right bx-sm"></i></a>
|
||||
</li>
|
||||
<li class="page-item last">
|
||||
<a class="page-link" href="javascript:void(0);"><i class="tf-icon bx bx-chevrons-right bx-sm"></i></a>
|
||||
|
||||
<!-- 마지막 페이지 이동 -->
|
||||
<li
|
||||
class="page-item last"
|
||||
@click="emitPageChange(navigateLastPage)"
|
||||
:class="{ disabled: isLastPage }"
|
||||
>
|
||||
<a class="page-link" href="javascript:void(0);">
|
||||
<i class="tf-icon bx bx-chevrons-right bx-sm"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup></script>
|
||||
<script setup>
|
||||
import { defineProps, defineEmits } from 'vue';
|
||||
|
||||
// Props 정의
|
||||
const props = defineProps({
|
||||
currentPage: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
pages: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
prePage: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
nextPage: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
isFirstPage: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
isLastPage: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
hasPreviousPage: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
hasNextPage: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
navigatePages: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
navigatepageNums: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
navigateFirstPage: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
navigateLastPage: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
// 이벤트 정의
|
||||
const emit = defineEmits(['update:currentPage']);
|
||||
|
||||
// 페이지 변경 메서드
|
||||
const emitPageChange = (page) => {
|
||||
if (page !== props.currentPage && page >= 1 && page <= props.pages) {
|
||||
emit('update:currentPage', page);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@ -11,10 +11,10 @@
|
||||
<div class="row">
|
||||
<!-- 정렬 셀렉트 박스 -->
|
||||
<div class="col-md-3 mb-4">
|
||||
<select class="form-select">
|
||||
<option selected>정렬 기준 선택</option>
|
||||
<option value="1">조회수</option>
|
||||
<option value="2">날짜</option>
|
||||
<select class="form-select" @change="handleSortChange">
|
||||
<option value="">정렬 선택</option>
|
||||
<option value="view">조회수</option>
|
||||
<option value="date">날짜</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@ -27,22 +27,33 @@
|
||||
</div>
|
||||
|
||||
<!-- 공지사항 게시물 리스트 -->
|
||||
<div class="row g-3">
|
||||
<board-card :posts="filteredList2" @click="goDetail" />
|
||||
<div class="row g-3 mt-8">
|
||||
<h3>공지사항</h3>
|
||||
<board-card :posts="noticeList" @click="goDetail" />
|
||||
</div>
|
||||
<!-- 일반 게시물 리스트 -->
|
||||
<div class="row g-3">
|
||||
<board-card :posts="paginatedList" @click="goDetail" />
|
||||
<div class="row g-3 mt-8">
|
||||
<h3>일반게시판</h3>
|
||||
<board-card :posts="generalList" @click="goDetail" />
|
||||
</div>
|
||||
|
||||
<!-- 페이지네이션 -->
|
||||
<div class="row g-3">
|
||||
|
||||
<div class="mt-8">
|
||||
<pagination
|
||||
:current-page="currentPage"
|
||||
:total-pages="totalPages"
|
||||
@update:page="changePage"
|
||||
<Pagination
|
||||
:currentPage="pagination.currentPage"
|
||||
:pages="pagination.pages"
|
||||
:prePage="pagination.prePage"
|
||||
:nextPage="pagination.nextPage"
|
||||
:isFirstPage="pagination.isFirstPage"
|
||||
:isLastPage="pagination.isLastPage"
|
||||
:hasPreviousPage="pagination.hasPreviousPage"
|
||||
:hasNextPage="pagination.hasNextPage"
|
||||
:navigatePages="pagination.navigatePages"
|
||||
:navigatepageNums="pagination.navigatepageNums"
|
||||
:navigateFirstPage="pagination.navigateFirstPage"
|
||||
:navigateLastPage="pagination.navigateLastPage"
|
||||
@update:currentPage="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -62,6 +73,22 @@ import axios from '@api';
|
||||
const generalList = ref([]);
|
||||
const noticeList = ref([]);
|
||||
const searchText = ref('');
|
||||
const selectedOrder = ref('');
|
||||
const sortDirection = ref('desc');
|
||||
const pagination = ref({
|
||||
currentPage: 1,
|
||||
pages: 1,
|
||||
prePage: 0,
|
||||
nextPage: 1,
|
||||
isFirstPage: true,
|
||||
isLastPage: false,
|
||||
hasPreviousPage: false,
|
||||
hasNextPage: false,
|
||||
navigatePages: 10,
|
||||
navigatepageNums: [1],
|
||||
navigateFirstPage: 1,
|
||||
navigateLastPage: 1
|
||||
});
|
||||
|
||||
// 상세 페이지 이동
|
||||
const goDetail = (id) => {
|
||||
@ -71,86 +98,101 @@ const goDetail = (id) => {
|
||||
// 검색 처리
|
||||
const search = (e) => {
|
||||
searchText.value = e.trim();
|
||||
fetchGeneralPosts(1);
|
||||
fetchNoticePosts(searchText.value);
|
||||
};
|
||||
|
||||
// 검색 결과 필터링(일반게시물)
|
||||
const filteredList = computed(() =>
|
||||
generalList.value.filter((item) =>
|
||||
item.title.toLowerCase().includes(searchText.value.toLowerCase())
|
||||
)
|
||||
);
|
||||
|
||||
// 검색 결과 필터링(공지사항)
|
||||
const filteredList2 = computed(() =>
|
||||
noticeList.value.filter((item) =>
|
||||
item.title.toLowerCase().includes(searchText.value.toLowerCase())
|
||||
)
|
||||
);
|
||||
|
||||
// 페이지네이션 상태
|
||||
const currentPage = ref(1); // 현재 페이지 번호
|
||||
const itemsPerPage = 10; // 한 페이지에 표시할 아이템 수
|
||||
|
||||
// 현재 페이지 데이터 계산
|
||||
const paginatedList = computed(() => {
|
||||
const start = (currentPage.value - 1) * itemsPerPage;
|
||||
const end = start + itemsPerPage;
|
||||
return filteredList.value.slice(start, end);
|
||||
});
|
||||
|
||||
// 총 페이지 수 계산
|
||||
const totalPages = computed(() => {
|
||||
return Math.ceil(filteredList.value.length / itemsPerPage);
|
||||
});
|
||||
|
||||
// 페이지 변경 함수
|
||||
const changePage = (page) => {
|
||||
if (page >= 1 && page <= totalPages.value) {
|
||||
currentPage.value = page;
|
||||
}
|
||||
// 정렬 변경 핸들러
|
||||
const handleSortChange = (event) => {
|
||||
const value = event.target.value;
|
||||
if (value === 'view') {
|
||||
selectedOrder.value = 'view';
|
||||
sortDirection.value = 'desc';
|
||||
} else if (value === 'date') {
|
||||
selectedOrder.value = 'date';
|
||||
sortDirection.value = 'desc';
|
||||
} else {
|
||||
selectedOrder.value = '';
|
||||
sortDirection.value = 'desc';
|
||||
};
|
||||
fetchGeneralPosts(1);
|
||||
};
|
||||
|
||||
// 게시물 데이터 로드(일반)
|
||||
const fetchPosts = async () => {
|
||||
const response = await axios.get("board/general");
|
||||
const fetchGeneralPosts = async (page = 1) => {
|
||||
const response = await axios.get("board/general", {
|
||||
params: {
|
||||
page: page,
|
||||
orderBy: selectedOrder.value,
|
||||
sortDirection: sortDirection.value,
|
||||
searchKeyword: searchText.value
|
||||
}
|
||||
});
|
||||
|
||||
if (response.data && response.data.data && Array.isArray(response.data.data.list)) {
|
||||
generalList.value = response.data.data.list.map((post, index) => ({
|
||||
if (response.data && response.data.data) {
|
||||
const data = response.data.data;
|
||||
// 게시물 리스트 업데이트
|
||||
generalList.value = data.list.map((post, index) => ({
|
||||
...post,
|
||||
id: post.id || index,
|
||||
img: post.img || null,
|
||||
likes: post.likes || 0,
|
||||
comments: post.comments || 0,
|
||||
views: post.cnt || 0,
|
||||
likes: post.likeCount || 0,
|
||||
comments: post.commentCount || 0,
|
||||
}));
|
||||
|
||||
// 페이지네이션 정보 업데이트
|
||||
pagination.value = {
|
||||
currentPage: data.pageNum,
|
||||
pages: data.pages,
|
||||
prePage: data.prePage,
|
||||
nextPage: data.nextPage,
|
||||
isFirstPage: data.isFirstPage,
|
||||
isLastPage: data.isLastPage,
|
||||
hasPreviousPage: data.hasPreviousPage,
|
||||
hasNextPage: data.hasNextPage,
|
||||
navigatePages: data.navigatePages,
|
||||
navigatepageNums: data.navigatepageNums,
|
||||
navigateFirstPage: data.navigateFirstPage,
|
||||
navigateLastPage: data.navigateLastPage
|
||||
};
|
||||
} else {
|
||||
console.error("데이터 오류:", response.data);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchPosts2 = async () => {
|
||||
const response = await axios.get("board/notices");
|
||||
// 게시물 데이터 로드(공지사항)
|
||||
const fetchNoticePosts = async () => {
|
||||
const response = await axios.get("board/notices", {
|
||||
params: {
|
||||
searchKeyword: searchText.value
|
||||
}
|
||||
});
|
||||
|
||||
if (response.data && response.data.data && Array.isArray(response.data.data)) {
|
||||
noticeList.value = response.data.data.map((post, index) => ({
|
||||
...post,
|
||||
id: post.id || index,
|
||||
img: post.img || null,
|
||||
likes: post.likes || 0,
|
||||
comments: post.comments || 0,
|
||||
views: post.cnt || 0,
|
||||
likes: post.likeCount || 0,
|
||||
comments: post.commentCount || 0,
|
||||
}));
|
||||
} else {
|
||||
console.error("데이터 오류:", response.data);
|
||||
}
|
||||
};
|
||||
|
||||
// 페이지 변경
|
||||
const handlePageChange = (page) => {
|
||||
if (page !== pagination.value.currentPage) {
|
||||
fetchGeneralPosts(page);
|
||||
}
|
||||
};
|
||||
|
||||
// 데이터 로드
|
||||
onMounted(() => {
|
||||
fetchPosts();
|
||||
fetchPosts2();
|
||||
fetchGeneralPosts();
|
||||
fetchNoticePosts();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 필요에 따라 스타일 추가 */
|
||||
</style>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user