왼쪽에 댓글 아이콘을 클릭하면
트윗 모달과 비슷하게 답글 모달창의 띄워 댓글을 달아줄 수 있도록 만들것이다.
CommentModal.vue를 생성하여 Tweet.vue에서 컴포넌트 등록을 한다.
<script>
import moment from "moment";
import CommentModal from "./CommentModal.vue";
import { ref } from "vue";
export default {
components: { CommentModal },
props: ["currentUser", "tweet"],
setup() {
const showCommentModal = ref(false);
return {
moment,
showCommentModal,
};
},
};
</script>
그리고 showCommentModal 함수를 만들어서 현재
모달 상태를 만들어주고 return 한다.
그리고 저 버튼이 클릭해야만 모달이 보여야하므로
<div class="flex justify-between">
<!-- 코멘트 버튼 -->
<div
@click="showCommentModal = true"
class="text-gray-500 hover:text-primary"
>
댓글 버튼에 클릭 이벤트를 걸어주고
CommentModal에는 v-if로 showCommentModal이 true일 때만 보여주게한다.
그리고 tweet의 내용을 props로 전달하고
close-modal함수도 전달하여 commentModal 컴포넌트에서도 모달창을 닫을 수 있도록 만들어준다.
<CommentModal
v-if="showCommentModal"
@close-modal="showCommentModal = false"
:tweet="tweet"
/>
</template>
CommentModal로 돌아와 디자인을 해주고
<template>
<div
class="relative z-10"
aria-labelledby="modal-title"
role="dialog"
aria-modal="true"
@click="$emit('close-modal')"
>
<div
class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"
></div>
<div class="fixed inset-0 z-10 w-screen overflow-y-auto">
<div
class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0"
>
<div
@click.stop
class="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg"
>
<div class="bg-white">
<div
class="flex items-center justify-between border-b border-gray-100 p-2"
>
<button
@click="$emit('close-modal')"
class="fas fa-times text-primary text-lg p-2 h-10 w-10 hover:bg-blue-50"
></button>
<div class="text-right sm:hidden mr-2">
<button
v-if="!tweetBody?.length"
class="bg-light text-sm font-bold text-white px-4 py-1 rounded-full"
>
답글
</button>
<button
v-else
@click="onAddTweet"
class="bg-primary hover:bg-dark text-sm font-bold text-white px-4 py-1 rounded-full"
>
답글
</button>
</div>
</div>
<div>
<!-- 오리지널 트윗 -->
<div class="flex px-4 pt-4 pb-3">
<div class="flex flex-col">
<img
:src="tweet.profile_image_url"
class="w-10 h-10 rounded-full hover:opacity-80 cursor-pointer"
/>
<div class="ml-5 w-0.5 h-full bg-gray-300 mt-2 -mb-1"></div>
</div>
<div class="ml-2 flex-1">
<div class="flex space-x-2">
<span class="font-bold text-sm">{{ tweet.email }}</span>
<span class="font-gray text-sm">@{{ tweet.username }}</span>
<span class="font-gray text-sm">{{
moment(tweet.created_at).fromNow()
}}</span>
</div>
<div class="">
{{ tweet.tweet_body }}
</div>
<div class="">
<span class="text-primary text-sm"
>@{{ tweet.username }}</span
>
<span class="font-gray text-sm">님에게 보내는 답글</span>
</div>
</div>
</div>
<!-- 트윗팅 섹션 -->
<div class="flex px-4 pb-4">
<img
:src="currentUser.profile_image_url"
class="w-10 h-10 rounded-full hover:opacity-80 cursor-pointer"
/>
<div class="ml-2 flex-1 flex flex-col">
<textarea
v-model="tweetBody"
placeholder="내 답글을 트윗합니다"
class="w-full text-lg font-bold focus:outline-none mb-3 resize-none"
rows="5"
></textarea>
<div class="text-right hidden sm:block">
<button
v-if="!tweetBody?.length"
class="bg-light text-sm font-bold text-white px-4 py-1 rounded-full"
>
답글
</button>
<button
v-else
@click="onCommentTweet"
class="bg-primary hover:bg-dark text-sm font-bold text-white px-4 py-1 rounded-full"
>
답글
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
여기에 내가 답글을 입력하고
답글 버튼을 클릭하면 해당 트윗에 답글이 달리도록 할거임
<script>
import { ref, computed } from "vue";
import store from "../store";
import moment from "moment";
import {
collection,
doc,
increment,
setDoc,
updateDoc,
} from "firebase/firestore";
import { db } from "../firebase";
export default {
props: ["tweet"],
setup(props, { emit }) {
const tweetBody = ref("");
const currentUser = computed(() => store.state.user);
//트윗 추가 함수 -> utils의 addTweet함수
const onCommentTweet = async () => {
try {
//커맨트 저장하기
const newCommentRef = doc(collection(db, "comments"));
await setDoc(newCommentRef, {
id: newCommentRef.id,
from_tweet_id: props.tweet.id,
tweet_body: tweetBody.value,
uid: currentUser.value.uid,
created_at: Date.now(),
});
tweetBody.value = "";
const updateTweetRef = doc(db, "tweets", props.tweet.id);
//tweet에서 comment 수 증가
await updateDoc(updateTweetRef, {
num_comments: increment(1),
});
emit("close-modal"); //상위 컴포넌트에 close-modal실행
} catch (e) {
console.log("트윗 에러 메시지", e);
}
};
return {
tweetBody,
onCommentTweet,
currentUser,
moment,
};
},
};
</script>
1. setDoc을 통해 답글 내용과 함께 그리고 어떤 글에 답글을 다는건지 알야하므로 props로 넘어오는 tweet의id도 함께 넣어준다.
2. tweets db를 보면 num_comments라고 답글 수를 나타냄 이 테이블의 값을 1 증가하기 위해 increment(1)를 사용한다.
답글을 달고나면 위와같이 답글 수가 나옴
파이어베이스에도 잘 update된것을 확인할 수 있다.
'FRONTEND > Vue' 카테고리의 다른 글
[Vue3 + vite + tailwindCSS] 좋아요 기능 추가 (0) | 2024.03.28 |
---|---|
[Vue3 + vite + tailwindCSS] 리트윗 기능 추가 (0) | 2024.03.28 |
[Vue3 + vite + tailwindCSS] 트윗 모달과 함수 연결 (0) | 2024.03.25 |
[Vue3 + vite + tailwindCSS] 트윗 모달 팝업 (0) | 2024.03.22 |
[Vue3 + vite + tailwindCSS] 트윗에 유저 정보 표시하기 (0) | 2024.03.22 |