Feat: Use api in article detail page

This commit is contained in:
jhynsoo 2024-05-21 15:56:30 +09:00
parent 9f340ee6ef
commit b83426e94c
4 changed files with 42 additions and 49 deletions

View File

@ -4,6 +4,7 @@ import { useRoute } from 'vue-router';
import BoardHeader from './BoardHeader.vue'; import BoardHeader from './BoardHeader.vue';
import { getArticle } from '@/api/article'; import { getArticle } from '@/api/article';
import CommentArea from './CommentArea.vue'; import CommentArea from './CommentArea.vue';
import { getComment } from '@/api/comment';
const route = useRoute(); const route = useRoute();
@ -14,30 +15,9 @@ const comments = ref([]);
getArticle(id, ({ data }) => { getArticle(id, ({ data }) => {
article.value = data; article.value = data;
}); });
getComment(id, ({ data }) => {
// FIXME: remove mock data comments.value = data;
setTimeout(() => { });
article.value = {
title: '제목',
text: '내용',
author: '작성자',
date: '2024-04-11 13:12:14',
};
comments.value = [
{
id: 1,
nickname: '닉네임',
date: '2024-04-11 13:12:14',
text: '댓글 내용',
},
{
id: 2,
nickname: '닉네임',
date: '2024-04-11 13:12:14',
text: '댓글 내용',
},
];
}, 100);
</script> </script>
<template> <template>
@ -46,7 +26,7 @@ setTimeout(() => {
<h1>{{ article.title }}</h1> <h1>{{ article.title }}</h1>
</template> </template>
<template #info> <template #info>
<div class="author">{{ article.author }}</div> <div class="author">{{ article.name }}</div>
<div class="date">{{ article.date }}</div> <div class="date">{{ article.date }}</div>
</template> </template>
</BoardHeader> </BoardHeader>
@ -56,9 +36,9 @@ setTimeout(() => {
<style scoped> <style scoped>
p { p {
margin: 20px; margin: 40px 20px 20px;
line-height: 1.6; line-height: 1.6;
padding-bottom: 20px; padding-bottom: 40px;
border-bottom: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border);
} }
</style> </style>

View File

@ -1,43 +1,52 @@
<script setup> <script setup>
import { getArticles } from '@/api/article'; import { getArticles } from '@/api/article';
import { ref , reactive } from 'vue'; import { ref, reactive, watch } from 'vue';
import { RouterLink } from 'vue-router'; import { RouterLink } from 'vue-router';
import FilledButton from '../common/FilledButton.vue'; import FilledButton from '../common/FilledButton.vue';
import PageNavigation from "../common/PageNavigation.vue";
const articles = ref([]); const articles = ref([]);
const params = reactive({ const params = reactive({
pageNo: 1, pageNo: 1,
key: 'all', key: 'all',
word: '' word: '',
}) });
const hasNextPage = ref(true);
const currentPage = ref(1) const lastElement = ref(null);
const totalpage = ref(1)
watch(lastElement, (el) => {
if (!el) {
return;
}
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && hasNextPage.value) {
params.pageNo += 1;
searchList();
}
},
{ threshold: 1 }
);
observer.observe(el);
});
function searchList() { function searchList() {
getArticles( getArticles(
params, params,
({ data }) => { ({ data }) => {
articles.value = data.articles if ((data?.articles?.length ?? 0) === 0) {
currentPage.value = data.page.pageNo hasNextPage.value = false;
totalpage.value = data.page.total return;
console.log(articles.value) }
console.log(currentPage.value) articles.value = [...articles.value, ...(data?.articles ?? [])];
console.log(totalpage.value)
}, },
(error) => { (error) => {
console.log(error) console.log(error);
} }
); );
} }
searchList() searchList();
function pageChange(value) {
params.pageNo = value
searchList()
}
</script> </script>
<template> <template>
@ -61,7 +70,7 @@ function pageChange(value) {
</RouterLink> </RouterLink>
</li> </li>
</ul> </ul>
<PageNavigation :currentPage="currentPage" :totalPage="totalpage" @page-change="pageChange" /> <div ref="lastElement"></div>
</template> </template>
<style scoped> <style scoped>

View File

@ -1,8 +1,10 @@
<script setup> <script setup>
import { useMemberStore } from '@/stores/memberStore';
import CommentForm from './CommentForm.vue'; import CommentForm from './CommentForm.vue';
import CommentList from './CommentList.vue'; import CommentList from './CommentList.vue';
const { articleId, comments } = defineProps({ articleId: Number, comments: Array }); const { articleId, comments } = defineProps({ articleId: Number, comments: Array });
const memberStore = useMemberStore();
</script> </script>
<template> <template>
@ -10,7 +12,7 @@ const { articleId, comments } = defineProps({ articleId: Number, comments: Array
<h2> <h2>
댓글 <span>{{ comments.length }}</span> 댓글 <span>{{ comments.length }}</span>
</h2> </h2>
<CommentForm :article-id="articleId" /> <CommentForm :article-id="articleId" v-if="memberStore.isLogin" />
<CommentList :comments="comments" /> <CommentList :comments="comments" />
</div> </div>
</template> </template>

View File

@ -2,6 +2,7 @@
import { ref } from 'vue'; import { ref } from 'vue';
import FilledButton from '../common/FilledButton.vue'; import FilledButton from '../common/FilledButton.vue';
import TextButton from '../common/TextButton.vue'; import TextButton from '../common/TextButton.vue';
import { addComment } from '@/api/comment';
const { id } = defineProps({ id: Number }); const { id } = defineProps({ id: Number });
const isActive = ref(false); const isActive = ref(false);
@ -20,6 +21,7 @@ function handleCancel() {
function handleSubmit() { function handleSubmit() {
console.log(id, text.value); console.log(id, text.value);
addComment({ id, text: text.value });
// TODO: add api call // TODO: add api call
text.value = ''; text.value = '';
isActive.value = false; isActive.value = false;