Vue递归实现评论列表

功能图

递归实现评论列表.JPG

<el-card style="margin-top: 30px">
              <div class="fbpl" style="margin-bottom: 5px">
                <span>发表评论</span>
              </div>
              <div style="">
                <textarea class="plcontent" id="comment-input" v-model="commentContent" placeholder="请输入评论内容" style="width: 100%; height: 100px;">
                </textarea>
              </div>
              <div style="margin-top: 10px; text-align: right">
                <el-button type="primary" @click="addCommentContent">评论</el-button>
              </div>
            </el-card>

            <el-card style="margin-top: 30px">
              <div style="">
                <div style="margin: 10px 0; font-size: 24px; padding: 10px 0; border-bottom: 1px solid #ccc; text-align: left">
                  评论列表
                </div>
                <div style=" text-align: left">
                  <div v-for="item in comments" :key="item.commentId" style="padding: 10px 0; border-bottom: 1px solid #ccc;">
                    <!-- 评论者信息 -->
                    <div style="display: flex; align-items: center;">
                      <el-avatar :size="50" :src="'https://edu-yc.oss-cn-beijing.aliyuncs.com/avatar/b70223e8672e10f69f0ca36e652507ca.png'"></el-avatar>
                      <div style="flex: 1; margin-left: 10px;">
                        <div style="color: black"><b>{{ item.userId }}:</b><span>{{ item.content }}</span></div>
                        <div style="width: 200px; margin-top: 15px">
                          <i class="el-icon-time"></i><span style="margin-left: 5px">{{ new Date(item.createdAt).toLocaleString() }}</span>
                        </div>
                        <!-- 回复按钮 -->
                        <el-button type="text" @click="showReplyDialog(item)">回复</el-button>
                      </div>
                    </div>

                    <!-- 子评论列表 -->
                    <div v-if="item.children && item.children.length" style="margin-left: 50px; background-color: aliceblue; padding: 10px; border-radius: 10px;">
                      <div v-for="sub in item.children" :key="sub.commentId" style="padding: 5px 0">
                        <b style="cursor: pointer" @click="reply(sub)">{{ sub.userId }}</b>
                        <span>回复
                          <span style="color: cornflowerblue">@{{ item.userId }}</span>
                          <span style="color: #666; margin-left: 10px">{{ sub.content }}</span>
                        </span>
                        <div style="width: 200px; margin-top: 15px">
                          <i class="el-icon-time"></i><span style="margin-left: 5px">{{ new Date(item.createdAt).toLocaleString() }}</span>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <el-dialog title="回复" :visible.sync="dialogFormVisible" width="40%">
                <el-form :model="replyComment">
                  <el-form-item label="内容" :label-width="100">
                    <el-input v-model="replyComment.content" autocomplete="off" style="width: 80%"></el-input>
                  </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                  <el-button @click="dialogFormVisible = false">取 消</el-button>
                  <el-button type="primary" @click="submitReply">确 定</el-button>
                </div>
              </el-dialog>
            </el-card>
  fetchArticleByid() {
      this.$request.get('/article/selectById', {
        params: {
          id: this.articleId
        }
      }).then(response => {

        if (response.code === '200' && response.data) {
          this.article = response.data;
          console.log('article:', this.article)
          console.log('blog:',)
        }
      })
    },
submitReply() {
      // 这里添加提交回复的逻辑
      console.log('Submitting reply:', this.replyContent, 'to', this.replyItem.userId);
      // 假设回复提交成功,隐藏模态框
      this.$request.post("/comments/addComment",{
        postId: this.articleId,
        userId: this.replyItem.userId,
        content: this.replyItem.content,
        parentId: this.replyItem.commentId,
      }).then(res=>{
        console.log(res)
      })
      this.dialogVisible = false;
      this.$message.success('回复成功!');
},
  addCommentContent(){
      this.$request.post('/comments/addComment',{
        postId: this.articleId,
        userId: this.user.id,
        content: this.commentContent,
        parentId: null,
      }).then(res=>{
        if (res.code === '200') {
          this.commentContent = '';
          this.fetchComments();
        }else {
          console.log('您的网络正在飞速赶来!!!')
        }
      })
    },
    fetchComments() {
      const postId = this.articleId; // 假设您通过路由参数传递postId
      this.$request.get(`/comments/getCommentsByPostId?postId=${postId}`)
          .then(response => {
            if (response.code === '200' && response.data) {
              this.comments = this.buildCommentTree(response.data);
              console.log('comments:', this.comments)
            } else {
              console.error('Failed to fetch comments:', response.msg);
            }
          })
          .catch(error => {
            console.error('Error fetching comments:', error);
          });
    },
    // 构建评论树
    buildCommentTree(comments) {
      // 创建一个映射,以commentId为键,评论对象为值
      const commentMap = new Map(comments.map(comment => [comment.commentId, comment]));

      // 初始化顶级评论数组
      const rootComments = [];

      // 构建评论树
      comments.forEach(comment => {
        if (comment.parentId === null || comment.parentId === undefined) {
          // 如果是顶级评论,添加到顶级数组
          rootComments.push(comment);
        } else {
          // 如果不是顶级评论,找到其父评论并添加到父评论的children数组
          const parentComment = commentMap.get(comment.parentId);
          if (parentComment) {
            parentComment.children = parentComment.children || [];
            parentComment.children.push(comment);
          }
        }
      });
      // 返回顶级评论数组
      return rootComments;
    },
  }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值