用戶評論功能設計[二](實現回覆功能)

在前面,咱們已是實現了用戶評論功能以及評論的實時顯示,如今,咱們來實現一下,用戶的回覆功能。實現效果以下所示:
javascript

回覆評論的流程

咱們梳理一下評論回覆流程:html

  1. 用戶點擊評論,input框獲取焦點,input框的placeholder變爲回覆 @nickname
  2. 用戶輸入評論內容,而後提交,向服務器發出請求
  3. 在頁面渲染用戶評論內容

細心的同窗可能會發現,當回覆成功後,頂部的xx條評論並無進行更新,由於在頁面顯示時,我並無將回復看成是評論來處理,因此數量並無增長java

回覆功能邏輯實現

評論對象事件綁定

<li class="comment_li" v-for="(item,index) in commentList" :key="item.id" @click="replyUser(item,index,-1)" >...</li>
複製代碼

從上面的代碼,能夠看出,咱們爲每一個評論對象綁定了一個replyUser(item,index,-1)的事件。那咱們如今來看一下,咱們在replyUser函數中作了什麼事情數據庫

replyUser(item, index, index2) { 
      item.index = index; // 爲每一個評論對象綁定一個index屬性,這個index的做用是爲了幫助咱們能更好的在commmentList中定位到該評論對象
      item.index2 = index2; // index2的做用是爲了幫助咱們區分回覆的級別。-1表明回覆的是根評論,其餘值表示回覆的是別人的回覆。
      this.replyUserComment = item;//replyUserComment的做用是爲了保存當前的評論對象,在data中定義
      this.commentPlaceholder = `回覆 @${item.nickname}:`;//修改placeHolder
      this.$refs.content.focus(); //input框獲取焦點
    },
複製代碼

通過上面的處理,咱們已經取得了咱們回覆的評論對象。數組

對評論內容的處理

<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':''">&#xe608;</i>
    </div>
</div>
複製代碼

在這裏,爲input框綁定了一個checkComment事件,在實現簡單評論功能時,它的邏輯是下面這樣的:服務器

checkComment() {
      if (this.comment_text == "") {
        Toast("評論內容不能爲空");
      } else {
        if (!this.isLogin) {
          this.$router.push({
            path: "/login"
          });
          return;
        }
        let to_user_id = ''; //由於評論是根評論,因此to_user_id和father_comment_id都爲空
        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: "剛剛",
          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);
          }
        );
      }
    },
複製代碼
  1. 由於咱們一開始實現的評論功能是發佈的根評論,沒有要回復誰,因此to_user_idfather_comment_id咱們置空。
  2. 如今,咱們要進行的操做是回覆用戶評論。咱們須要明確回覆的是哪一個用戶,所回覆的是哪條評論。由剛纔的點擊操做,咱們已經能夠明確這兩個信息了。所以,咱們要修改一下上面的邏輯:
checkComment() {
      if (this.comment_text == "") {
        Toast("評論內容不能爲空");
      } else {
        if (!this.isLogin) {
          this.$router.push({
            path: "/login"
          });
          return;
        }
        let to_user_id = ''; //由於評論是根評論,因此to_user_id和father_comment_id都爲空
        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: "剛剛",
          nickname: this.userInfo.nickname
        };
----------------------------------------------------
----------------------------------------------------
        if(this.replyUserComment){//若是評論對象不爲null
            to_user_id = this.replyUserComment.from_user_id; // 讓回覆對象指向評論者
            father_comment_id = this.replyUserComment.id //讓新評論的father_comment_id指向評論的id
        }
-------------------------------------------------------
-------------------------------------------------------
        sendComment({ to_user_id, father_comment_id, comment, video_id }).then(
          val => {
            this.comment_text = "";
            this.hasSend = true;
            this.commentList.unshift(newComment);
          }
        );
      }
    },
複製代碼

實時渲染回覆內容

如今已經實現了回覆保存到數據庫的功能。可是一樣沒有實時渲染到頁面上。 所以,咱們要向以前同樣,生成一個新的評論對象,並將這個對象插入到數組中去。但回覆對象的插入與根評論的插入邏輯上存在差別,咱們先來看下面bilibili的評論圖: ide

回覆也能夠看成評論進行回覆。在項目中,咱們將回復劃分爲兩類,一類是一級回覆,一類是二級回覆。函數


對於評論和回覆來講,通常採用的都是以下的嵌套的數據格式:ui

{
    avatar:'xxxxxxxxxxxx',
    nickname:'xxxxxxxxxxxxx',
    comment:'xxxxxxxxxxxxxx',
    crete_time:'xxxxxxxxxxxxx',
    child_comments:[
        {
             avatar:'xxxxxxxxxxxx',
            nickname:'xxxxxxxxxxxxx',
            comment:'xxxxxxxxxxxxxx',
            crete_time:'xxxxxxxxxxxxx',
        }
        ......
    ]
}
複製代碼

  • 對於一級回覆,咱們是直接插入到頭部。
  • 對於二級回覆,咱們是直接插入到尾部。 在前面replyUserComment回調函數中,咱們進行了以下處理:
replyUser(item, index, index2) { 
      item.index = index; // 爲每一個評論對象綁定一個index屬性,這個index的做用是爲了幫助咱們能更好的在commmentList中定位到該評論對象
      item.index2 = index2; // index2的做用是爲了幫助咱們區分回覆的級別。-1表明回覆的是根評論,其餘值表示回覆的是別人的回覆。
      this.replyUserComment = item;//replyUserComment的做用是爲了保存當前的評論對象,在data中定義
      this.commentPlaceholder = `回覆 @${item.nickname}:`;//修改placeHolder
      this.$refs.content.focus(); //input框獲取焦點
    },
複製代碼

有了上面的圖,咱們就能很好理解了。因而咱們對於一級回覆,很容寫出下面的代碼:this

let index = this.replyUserComment.index;
let index2 = this.replyUserComment.index2;
if (this.replyUserComment.index2 == -1) {
//將一級回覆插入到子評論的頭部
this.commentList[index].child_comments.unshift(newComment);
} else {
//將二級回覆插入到子評論的尾部
this.commentList[index].child_comments.push(newComment)
}
複製代碼

完整代碼

replyUser(item, index, index2) {
      item.index = index;
      item.index2 = index2;
      this.replyUserComment = item;
      this.commentPlaceholder = `回覆 @${item.nickname}:`;
      this.$refs.content.focus();
    },
 checkComment() {
      if (this.comment_text == "") {
        Toast("評論內容不能爲空");
      } else {
        if (!this.isLogin) {
          this.$router.push({
            path: "/login"
          });
          return;
        }
        let father_comment_id = ""; // 默認父評論爲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: "剛剛",
          nickname: this.userInfo.nickname
        };
        if (this.replyUserComment) {
          // 說明不是根評論,而是子評論
          father_comment_id = this.replyUserComment.id; // 讓father_comment_id 指向這個評論
          to_user_id = this.replyUserComment.from_user_id; // 讓to_user_id指向父級評論的from_user_id
        }
        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) {
                //回覆一級人
                this.commentList[index].child_comments.unshift(newComment);
              } else {
                //回覆二級人
                this.commentList[index].child_comments.push(newComment)
              }
            }
          }
        );
      }
    },
複製代碼

到目前爲止,用戶的回覆功能也是實現了,接下來,就相對輕鬆了,還剩下,評論功能的點贊。

未完待續....

相關文章
相關標籤/搜索