In the previous, we have implemented the user comment function and real-time display of comments, now, let’s implement the user reply function. The implementation effect is as follows:
Process for responding to comments
Let’s review the comment response process:
- The user clicks on the comment,
input
Box gets focus,input
The boxplaceholder
intoReply @ nickname
- The user enters a comment and submits it, making a request to the server
- Render user comments on the page
Careful students may find that when the reply is successful, the top of theXx comments
I didn’t update it because I didn’t treat the responses as comments when the page was displayed, so the number didn’t increase
Return function logic implementation
Comment object event binding
<li
class="comment_li"
v-for="(item,index) in commentList"
:key="item.id"
@click="replyUser(item,index,-1)"
>.</li>
Copy the code
From the code above, you can see that we bind a replyUser(item,index,-1) event to each comment object. So what are we doing in the replyUser function
replyUser(item, index, index2) {
item.index = index; // Bind an index attribute to each comment object. This index is used to help us better locate the comment object in the commmentList
item.index2 = index2; // Index2 is used to help us distinguish the level of reply. -1 indicates that the reply is a root comment, and other values indicate that the reply is from someone else.
this.replyUserComment = item;//replyUserComment is used to save the current comment object, defined in data
this.commentPlaceholder = ` reply @${item.nickname}: `;/ / modify the placeHolder
this.$refs.content.focus(); // Input box gets focus
},
Copy the code
After the above processing, we have obtained the comment object of our reply.
Handling of comments
<div class="comment_input_box" v-show="commentPop">
<input
:placeholder="commentPlaceholder"
class="comment_input"
v-model="comment_text"
ref="content"
@click="checkComment"
/>
<div class="comment_input_right" @click="checkComment">
<i class="iconfont icon-fasong comment_i" :class="canSend? 'comment_i_active':''"></i>
</div>
</div>
Copy the code
In this case, the input box is bound to a checkComment event, whose logic looks like this when implementing simple comments:
checkComment() {
if (this.comment_text == "") {
Toast("Comments can't be empty.");
} else {
if (!this.isLogin) {
this.$router.push({
path: "/login"
});
return;
}
let to_user_id = ' '; // Because the comment is root, to_user_id and father_comment_id are empty
let father_comment_id = ' ';
const comment = this.comment_text;
const video_id = this.video_id;
const id = Date.now();
const newComment = {
avatar: this.userInfo.avatar,
comment,
id,
create_time: "Just".nickname: this.userInfo.nickname
};
sendComment({ to_user_id, father_comment_id, comment, video_id }).then(
val= > {
this.comment_text = "";
this.hasSend = true;
this.commentList.unshift(newComment); }); }},Copy the code
- Because the comment function we implemented at the beginning is the root comment of the post, there is no reply to who, so
to_user_id
andfather_comment_id
Let’s leave it empty. - Now, what we want to do is reply to user comments. We need to be clear about which user to reply to and which comment to reply to. We already know these two things by clicking on them. Therefore, we need to modify the above logic:
checkComment() {
if (this.comment_text == "") {
Toast("Comments can't be empty.");
} else {
if (!this.isLogin) {
this.$router.push({
path: "/login"
});
return;
}
let to_user_id = ' '; // Because the comment is root, to_user_id and father_comment_id are empty
let father_comment_id = ' ';
const comment = this.comment_text;
const video_id = this.video_id;
const id = Date.now();
const newComment = {
avatar: this.userInfo.avatar,
comment,
id,
create_time: "Just".nickname: this.userInfo.nickname
};
----------------------------------------------------
----------------------------------------------------
if(this.replyUserComment){// If the comment object is not null
to_user_id = this.replyUserComment.from_user_id; // Redirect the reply object to the commenter
father_comment_id = this.replyUserComment.id // Make the father_comment_id of the new comment point to the comment ID} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- sendComment({ to_user_id, father_comment_id, comment, video_id }).then(val= > {
this.comment_text = "";
this.hasSend = true;
this.commentList.unshift(newComment); }); }},Copy the code
Render replies in real time
You have now implemented the ability to save replies to the database. But again, it doesn’t render to the page in real time. So, as before, we generate a new comment object and insert it into the array. However, there is a logical difference between the insertion of the reply object and the insertion of the root comment. Let’s take a look at bilibili’s comment graph below:
A reply can also be a comment. In the project, we divided the responses into two categories, one is the primary response and the other is the secondary response.
For comments and replies, the following nested data format is generally used:
{
avatar:'xxxxxxxxxxxx'.nickname:'xxxxxxxxxxxxx'.comment:'xxxxxxxxxxxxxx'.crete_time:'xxxxxxxxxxxxx'.child_comments:[
{
avatar:'xxxxxxxxxxxx'.nickname:'xxxxxxxxxxxxx'.comment:'xxxxxxxxxxxxxx'.crete_time:'xxxxxxxxxxxxx',}... ] }Copy the code
- For the first level reply, we insert it directly into the header.
- For the secondary response, we insert directly to the tail. In the previous
replyUserComment
In the callback function, we do the following:
replyUser(item, index, index2) {
item.index = index; // Bind an index attribute to each comment object. This index is used to help us better locate the comment object in the commmentList
item.index2 = index2; // Index2 is used to help us distinguish the level of reply. -1 indicates that the reply is a root comment, and other values indicate that the reply is from someone else.
this.replyUserComment = item;//replyUserComment is used to save the current comment object, defined in data
this.commentPlaceholder = ` reply @${item.nickname}: `;/ / modify the placeHolder
this.$refs.content.focus(); // Input box gets focus
},
Copy the code
With the picture above, we can understand it very well. So we can write the following code for the first level reply:
let index = this.replyUserComment.index;
let index2 = this.replyUserComment.index2;
if (this.replyUserComment.index2 == - 1) {
// Insert the first level reply into the head of the child comment
this.commentList[index].child_comments.unshift(newComment);
} else {
// Insert the secondary reply at the end of the child comment
this.commentList[index].child_comments.push(newComment)
}
Copy the code
The complete code
replyUser(item, index, index2) {
item.index = index;
item.index2 = index2;
this.replyUserComment = item;
this.commentPlaceholder = ` reply @${item.nickname}: `;
this.$refs.content.focus();
},
checkComment() {
if (this.comment_text == "") {
Toast("Comments can't be empty.");
} else {
if (!this.isLogin) {
this.$router.push({
path: "/login"
});
return;
}
let father_comment_id = ""; // The default parent comment is null
let to_user_id = "";
let video_id = this.video_id;
let comment = this.comment_text;
const id = Date.now();
const newComment = {
avatar: this.userInfo.avatar,
comment,
id,
create_time: "Just".nickname: this.userInfo.nickname
};
if (this.replyUserComment) {
// This is not a root comment, but a child comment
father_comment_id = this.replyUserComment.id; // Make father_comment_id point to this comment
to_user_id = this.replyUserComment.from_user_id; // make to_user_id point to from_user_id of the parent comment
}
sendComment({ to_user_id, father_comment_id, comment, video_id }).then(
val= > {
this.comment_text = "";
this.hasSend = true;
if (!this.replyUserComment) {
this.commentList.unshift(newComment);
} else {
let index = this.replyUserComment.index;
let index2 = this.replyUserComment.index2;
if (this.replyUserComment.index2 == - 1) {
// Return to level 1
this.commentList[index].child_comments.unshift(newComment);
} else {
// Reply to secondary person
this.commentList[index].child_comments.push(newComment) } } } ); }},Copy the code
So far, the user’s reply function is also realized, then, it is relatively easy, there is still, the comment function of the like.
To be continued….