로그인 후에는 마이로그에 댓글을 쓸 수 있습니다.
ChatGPT에게 물었습니다.
post에 댓글을 쓰고 싶어
ChatGPT
게시물(Post)에 댓글 기능을 구현하려면, 댓글을 Firestore에 저장하고, 이를 화면에 실시간으로 표시하는 구조로 설계할 수 있습니다. 댓글 기능은 기본적으로 입력 폼을 통해 댓글을 작성하고, Firestore에 저장한 후, 저장된 댓글을 다시 불러와 화면에 표시하는 방식입니다. 여기서는 Vue.js, Vuex, Firestore를 사용하여 댓글 작성 및 불러오기 기능을 구현하는 방법을 설명하겠습니다.
1. Firestore에서 댓글 컬렉션 구조
게시물(post)마다 여러 개의 댓글이 있을 수 있습니다. Firestore에서는 하위 컬렉션을 사용하여 게시물마다 댓글을 관리할 수 있습니다.
Firestore 구조 예시:
- posts (컬렉션)
- postId (문서)
- comments (하위 컬렉션)
- commentId (문서)
- content: "This is a comment"
- author: "User123"
- createdAt: serverTimestamp()
- commentId (문서)
- comments (하위 컬렉션)
2. Firestore에 댓글 저장하기 (Vuex의 actions 사용)
Vuex에서 댓글을 저장하는 action을 정의한 후, Firestore에 댓글을 추가하는 로직을 작성합니다.
Vuex Store (store.js)
import { getFirestore, collection, addDoc, serverTimestamp, query, orderBy, getDocs } from "firebase/firestore";
const db = getFirestore();
const store = new Vuex.Store({
state: {
comments: [], // 댓글 목록 저장
},
mutations: {
setComments(state, comments) {
state.comments = comments;
},
addComment(state, comment) {
state.comments.push(comment);
},
},
actions: {
async fetchComments({ commit }, postId) {
try {
const q = query(collection(db, "posts", postId, "comments"), orderBy("createdAt", "asc"));
const querySnapshot = await getDocs(q);
const comments = [];
querySnapshot.forEach((doc) => {
comments.push({ id: doc.id, ...doc.data() });
});
commit('setComments', comments); // 댓글을 상태에 저장
} catch (error) {
console.error("댓글 가져오기 실패:", error);
}
},
async addComment({ commit }, { postId, content, author }) {
try {
const commentRef = await addDoc(collection(db, "posts", postId, "comments"), {
content: content,
author: author,
createdAt: serverTimestamp(),
});
const newComment = { id: commentRef.id, content, author, createdAt: new Date() };
commit('addComment', newComment); // 새 댓글을 상태에 추가
} catch (error) {
console.error("댓글 추가 실패:", error);
}
},
},
});
export default store;
3. Vue 컴포넌트에서 댓글 기능 구현
댓글 작성 화면 (PostComments.vue)
<template>
<div>
<h3>Comments</h3>
<!-- 댓글 목록 -->
<ul v-if="comments.length > 0">
<li v-for="comment in comments" :key="comment.id">
<strong>{{ comment.author }}</strong>: {{ comment.content }}
</li>
</ul>
<!-- 댓글 작성 폼 -->
<div>
<input v-model="newComment" placeholder="Write a comment..." />
<button @click="submitComment">Add Comment</button>
</div>
</div>
</template>
<script>
export default {
props: {
postId: {
type: String,
required: true,
},
},
data() {
return {
newComment: '',
};
},
computed: {
comments() {
return this.$store.state.comments;
},
},
methods: {
async submitComment() {
const author = "Anonymous"; // 여기서 사용자 정보를 가져올 수 있음
if (this.newComment.trim()) {
await this.$store.dispatch('addComment', {
postId: this.postId,
content: this.newComment,
author: author,
});
this.newComment = ''; // 댓글 입력 필드 초기화
}
},
},
mounted() {
// 컴포넌트가 로드되면 해당 게시물의 댓글을 불러옴
this.$store.dispatch('fetchComments', this.postId);
},
};
</script>
4. 설명
- fetchComments: 특정 게시물(postId)에 달린 댓글을 Firestore에서 가져와 상태에 저장하는 Vuex action입니다.
- addComment: 댓글을 Firestore의 해당 게시물 하위 컬렉션에 추가하는 Vuex action입니다. 댓글이 성공적으로 추가되면 상태에 즉시 반영됩니다.
- mounted: 컴포넌트가 마운트되면 fetchComments를 호출하여 게시물에 달린 모든 댓글을 불러옵니다.
- submitComment: 댓글을 작성하고 제출 버튼을 클릭하면 Firestore에 댓글을 저장하는 액션을 실행합니다.
5. 추가 기능
댓글 삭제 기능
import { deleteDoc, doc } from "firebase/firestore";
async deleteComment({ postId, commentId }) {
const commentRef = doc(db, "posts", postId, "comments", commentId);
try {
await deleteDoc(commentRef);
console.log("댓글이 삭제되었습니다.");
} catch (error) {
console.error("댓글 삭제 실패:", error);
}
}
댓글 수정 기능
import { updateDoc, doc } from "firebase/firestore";
async updateComment({ postId, commentId, newContent }) {
const commentRef = doc(db, "posts", postId, "comments", commentId);
try {
await updateDoc(commentRef, {
content: newContent,
updatedAt: serverTimestamp(), // 수정된 시간 기록
});
console.log("댓글이 수정되었습니다.");
} catch (error) {
console.error("댓글 수정 실패:", error);
}
}
요약
Firestore 하위 컬렉션을 사용하여 게시물마다 댓글을 관리할 수 있습니다. Vuex의 actions를 사용하여 댓글을 작성하고, Firestore에 저장하며, 이를 상태로 관리할 수 있습니다. 컴포넌트에서 댓글 작성 폼과 목록을 보여주고, 작성된 댓글을 실시간으로 반영합니다. 추가적으로 댓글 수정 및 삭제 기능도 쉽게 구현할 수 있습니다. 이 구조를 기반으로 Firestore와 Vuex를 사용하여 댓글 기능을 쉽게 확장할 수 있습니다.
'Vue로 PWA 개발' 카테고리의 다른 글
33. mylog 답글 (0) | 2024.10.26 |
---|---|
32. mylog 댓글 쓰기 구현 (0) | 2024.10.26 |
30. mylog 수정, 내 마이로그 보기 구현 (0) | 2024.10.25 |
29. mylog 모아보기 (0) | 2024.10.25 |
28. mylog 수정 (0) | 2024.10.25 |