Vue + semanticUI + Java 实现多级评论

交友

  • 背景: 最近在弄一个博客网站,前端是vue + semanticUI ,后台用的springboot。在弄到评论这一块的时候,不知道级联嵌套评论怎么搞,从上午想到现在想出来了,特来记录一下

后台

后台是通过树来实现的。
数据库的表结构如下所示:
在这里插入图片描述
需要做的就是通过这个表,构建一个树,java代码如下:

package cn.zi10ng.blog.util;

import cn.zi10ng.blog.domain.CommentInfo;
import cn.zi10ng.blog.domain.Node;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Zi10ng
 * @date 2019年8月24日21:20:16
 */
public class TreeUtils {

    /**
     * 把评论信息的集合转化为一个树
     */
    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;
    }
}

前端

前端我用的semanticUI这个css和vue,现在我们主要的任务就是把后端的树结构在前端展示出来

因为对前端不是太熟,如果有前端dalao看见不妨指点一二

  • 纯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实现多级评论呢?
这里主要还是用了递归,对于一个后端狗来说,只知道原理但却不知如何在前端实现是最痛苦的QAQ

解决方法就是把多级评论封装为一个组件,这样就可以了,代码如下:

  • 组件
<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://picsum.photos/id/234/100/100'
    }
  }
}
</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了

在这里插入图片描述

发布了100 篇原创文章 · 获赞 142 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/coder_what/article/details/100063701