Vue + Java 实现多级评论

犹豫就会败北,果断就能白给!


记录:

  • 最近在整一个博客系统,看了demo 的前端发现他并没有实现多级评论,但这个其实还是蛮常见的,于是就想自己实现一下,想了好久,查了一些资料,终于搞出来了,整了一个小 demo,现在记录一下

后台

后台就是通过树来实现。
通过数据库的表来构建一个树。

package com.ekin.blog.common.utils;

import cn.ekin.blog.po.entity.CommentInfo;
import cn.ekin.blog.common.domain.Node;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: ekin
 * @Date: 2021/6/14 10:21
 */
public class TreeUtil {

     // 把评论信息的集合转化为一个树
    public Node buildTree(List<CommentInfo> commentInfo, long id){
        Node tree = new Node();
        List<Node> children = new ArrayList<>();
        List<Node> nodeList = new ArrayList<>();
        for (CommentInfo info : commentInfo) {
            children.add(buildNode(info));
        }
        tree.setId(id);
        tree.setChildren(children);
        for (Node child : children) {
            Node node = findNode(children, child.getParentId());
            List<Node> nodes = new ArrayList<>();
            if (node != null) {
                if (node.getChildren() != null) {
                    nodes = node.getChildren();
                    nodes.add(child);
                    node.setChildren(nodes);
                }else {
                    nodes.add(child);
                    node.setChildren(nodes);
                }
                nodeList.add(child);
            }
        }
        for (Node node : nodeList) {
            children.remove(node);
        }
        return tree;
    }

    private Node findNode(List<Node> nodes, long id){
        for (Node node : nodes) {
            if (node.getId() == id) {
                return node;
            }
        }
        return null;
    }

    private Node buildNode(CommentInfo info){
        Node node = new Node();
        node.setId(info.getId());
        node.setParentId(info.getParentId());
        node.setObject(info);
        node.setChildren(null);

        return node;
    }
}

前端

前端是用的 elementUI 和 Vue,不得不说作为一个后端狗写前端真是太折磨了…

CSS:

      <div class="comment" v-for="articleComment in articleCommentTree.children" :key="articleComment.object.id">
          <a class="avatar">
            <img :src="imgSrc" alt="头像">
          </a>
          <div class="content">
            <a class="author">{{articleComment.object.name}}</a>
            <div class="metadata">
              <span class="date">{{articleComment.object.createByStr}}</span>
            </div>
            <div class="text">{{articleComment.object.content}} </div>
            <div class="actions">
              <a class="reply">回复</a>
            </div>
          </div>
            <div v-if="articleComment.children != null" class="comments">
    			<div class="comment" v-for="subArticleComment in children" :key="subArticleComment.object.id">
      				<a class="avatar">
        				<img :src="imgSrc" alt="头像">
      				</a>
      			<div class="content">
        			<a class="author">{{subArticleComment.object.name}}</a>
        			<div class="metadata">
          			<span class="date">{{subArticleComment.object.createByStr}}</span>
       			</div>
        		<div class="text">{{subArticleComment.object.content}} </div>
        		<div class="actions">
          		<a class="reply">回复</a>
       		 </div>
      		</div>
    </div>
  </div>
</div>

到这里也只是一个静态页面,也只能实现到二级评论。那么如何实现多级评论呢?
可以用 vue 的递归来实现。

将多级评论封装为一个组件

<template>
  <div class="multistage">
  <div v-if="children != null" class="comments">
    <div class="comment" v-for="subArticleComment in children" :key="subArticleComment.object.id">
      <a class="avatar">
        <img :src="imgSrc" alt="头像">
      </a>
      <div class="content">
        <a class="author">{{subArticleComment.object.name}}</a>
        <div class="metadata">
          <span class="date">{{subArticleComment.object.createByStr}}</span>
        </div>
        <div class="text">{{subArticleComment.object.content}} </div>
        <div class="actions">
          <a class="reply">回复</a>
        </div>
      </div>
      <multistage :children="subArticleComment.children"/>
    </div>
  </div>
  </div>
</template>

<script>
export default {
  name: 'multistage',
  props: ['children'],
  data () {
    return {
      imgSrc: 'https://www.static.talkxj.com/avatar/user.png'
    }
  }
}
</script>
<style scoped>
</style>

调用

<div class="comment" v-for="articleComment in articleCommentTree.children" :key="articleComment.object.id">
          <a class="avatar">
            <img :src="imgSrc" alt="头像">
          </a>
          <div class="content">
            <a class="author">{{articleComment.object.name}}</a>
            <div class="metadata">
              <span class="date">{{articleComment.object.createByStr}}</span>
            </div>
            <div class="text">{{articleComment.object.content}} </div>
            <div class="actions">
              <a class="reply">回复</a>
            </div>
          </div>
           <multistage :children="articleComment.children"/>
        </div>

到这里就OK了!

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值