【开发实践】vue2.0+MySQL+mybatis 实现微博评论 —— 一问多答式的评论模块

       在信息发达的今天,社交平台发展得很快,很多大事件引发很多评论。是否思考过评论模块如何实现呢?评论模块一旦设计得不好,就是一个疯狂套娃得过程hhhh……

一、评论模式

1、一问一答模式

【经典例子】:微信朋友圈

这种模式比较简单,数据库设计如下:

这种模式下,只需要关联一个回复用户的ID即可。

【业务场景】:

仅仅适合评论较少的业务开发,类似于微信朋友圈这种朋友圈子。

2、一问多答模式(本文重点)

【经典例子】微博、知乎等等大型社交平台

数据库的设计

对一问一答形式的评论的数据库表做了改变,添加了关联的评论id,即是顶级评论的id。

【注意】

 这里回复ID和关联的父级评论ID不一样,对于前者,作用便是清楚谁回复的你;而对于后者,作用就是所关联的顶级评论,具体就是在某条顶级评论下展开的评论。这里所用关系类似于文件的目录,顶级目录下面展开,还可能包括其他的一些目录。

二、具体实现

1、前端模板

这里我只展示评论模块(需要完整前端私聊发,免费

【需要注意的问题】

  • 折叠版id绑定自己设置,一定要唯一,否则会报错或者是展开到隔壁去了。
  • 评论数据的绑定,注意折叠版同时展开的问题,如果共用多个,可能会出现数据紊乱。
<!--评论模块-->
<div class="post__collapse collapse" :id="`collapse${i}`">
    <form action="#" class="post__form">
        <input type="text" placeholder="说点什么吧!" :id="`comment${i}`">
        <button type="button" @click="addComment(i,b.id)"><i class="icon ion-ios-paper-plane"
                                                             title="点击确认"></i></button>
    </form>

    <div class="post__comment" v-for="(com,index) in commentParentDisplay['Id'+i]"
         :key="com.id">
        <a href="javascript:;" @click="goToOtherUserInfo(com.userId)" class="post__comment-img">
            <img :src="com.icon || '/imgs/icons/default-icon.png'" alt="">
        </a>
        <div class="post__comment-title">
            <h5><a href="javascript:;" @click="goToOtherUserInfo(com.userId)">{{com.nickName}}</a></h5>
            <p>{{com.createTime | dateFilter }}</p>
        </div>
        <div class="post__dropdown">
            <a class="dropdown-toggle post__dropdown-btn" href="#" role="button"
               data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <i class="icon ion-md-more"></i>
            </a>
            <ul class="dropdown-menu dropdown-menu-right post__dropdown-menu"
                aria-labelledby="dropdownMenu3">
                <li><a @click="callBackParent(com,i)" data-toggle="modal"
                       :data-target="b.canCom==true ?'#myModal':''">回复</a>
                </li>
            </ul>
        </div>
        <span class="post__comment-text">{{com.content}}
            <a class="post__comments collapsed" data-toggle="collapse"
               :href="`#collapse${i}-${index}`"
               role="button" aria-expanded="false" :aria-controls="`collapse${i}-${index}`">&nbsp;<span>{{com.childList | getCommentNum}}</span></a>
        </span>

        <!--回复评论-->
        <div class="col-sm-12">
            <div class="col-sm-1" style="height:1px;width:1px;background:white">
            </div>
            <div class="col-sm-11 post__collapse collapse" :id="`collapse${i}-${index}`">
                <div class="post__comment" v-for="child in com.childList">
                    <a href="javascript:;" @click="goToOtherUserInfo(child.userId)" class="post__comment-img">
                        <img :src="child.icon || '/imgs/icons/default-icon.png'" alt="">
                    </a>
                    <div class="post__comment-title">
                        <h5><a href="javascript:;" @click="goToOtherUserInfo(child.userId)">{{child.nickName}}</a></h5>
                        <p>{{child.createTime|dateFilter}}</p>
                    </div>
                    <div class="post__dropdown">
                        <a class="dropdown-toggle post__dropdown-btn" role="button"
                           data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                            <i class="icon ion-md-more"></i>
                        </a>
                        <ul class="dropdown-menu dropdown-menu-right post__dropdown-menu"
                            aria-labelledby="dropdownMenu3">
                            <li><a @click="callBackChild(com.id,child,i)" data-toggle="modal"
                                   :data-target="b.canCom==true ?'#myModal':''">回复</a></li>
                        </ul>
                    </div>
                    <p class="post__comment-text">
                        <span style="color: deepskyblue">{{child.answerId| callBackPerson(com.childList)}}</span>
                        {{child.content}}
                    </p>
                </div>
            </div>
        </div>
        <!--回复评论-->

        </div>

    </div>
</div>
<!--评论模块结束-->

这里数据都是vue发送Ajax请求获得json数据,遍历数据。

2、后端实现

controller层实现

根据文章id,先查寻所有父级评论,即关联评论id为0,在依次遍历出父级评论下所有的子级评论。为了前端方便,笔者这里的做法是,在父级评论中有子级评论的数组,方便前端遍历评论。

    @Override
    public Result getCommentAllParent(Long blogId) {
        //查询所有父级别评论
        QueryWrapper<BlogCommentAndUser> parent = new QueryWrapper<>();
        parent.eq("blog_id",blogId).eq("parent_id", PARENT_OPTION).orderByAsc("create_time");
        List<BlogCommentAndUser> blogCommentAndUserList = this.baseMapper.selectList(parent);
        for(BlogCommentAndUser blogParent: blogCommentAndUserList){
            blogParent.setChildList(getCommentByParentId(blogId,blogParent.getId()));
        }
        return Result.success(blogCommentAndUserList);
    }

 三、效果展示

1、整体分享预览

2、评论的多级展开

四、资源获取

资源获取:https://download.csdn.net/download/m0_46013789/88713028


如果您觉得文章真的有用的话,三连支持一下吧!!![抱拳]

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫蜜柚子茶

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值