首先,先贴一下效果图
大概就是要做成这个样子。上面的实现完全靠js。数据是写在data中的死数据,这样我们就能先把前端需要的数据结构确定后,就只需要从后台取出数据,生成对应的格式就好了。
再次:先说一下这样实现的不足之处:回复列表是根据回复信息数组顺序来显示的,所以,时间顺序会打乱三个人之间的回复顺序,会显得上句不搭下句,还好加了,谁回复谁,才显得不那么吃力。有待改进。
还有,自己也可以回复自己,这个可以做一个评论限制,目前还没去优化。
这里我提一下,使用的界面UI框架,是colorUI,一个非常不错的UI框架,使用简单,方便。
这里贴一下他的GitHub地址:https://github.com/weilanwl/ColorUI
我用的是:colorUI中的卡片部分作为前端评论的界面。
具体操作:
第一部分:思考评论的数据结构。根据你自己的需求,这里我贴上我的,因为是很常见的评论+回复+再回复
首先:js中data数据分为两个表,一个评论表,和回复表(包括再回复),数据库中,评论和回复我是放在同一个表中,所以下面js中的评论和回复数据的comment_id是唯一的,
实现原理:循环显示评论表,再在每条评论下筛选属于这条评论的回复以及再回复。
js数据格式:
//评论数据
comment_list:[
{
comment_id:1, //评论id
comment_pr_id:1, //评论所属文章id
comment_user_name:'九月', //评论人姓名
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg', //评论人头像
comment_text:"做的不错嘛", //评论内容
comment_time:'2019年3月20日', //评论时间
reply_id: 0, //回复谁的评论,评论表全部默认为0
parent_id: 0, //评论所属哪个评论id下面的,评论表全部默认为0
reply_name:'' //回复评论人的昵称 评论表全部默认为''
},
{
comment_id: 4,
comment_pr_id: 1,
comment_user_name: '九月',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "可以可以",
comment_time: '2019年3月20日',
reply_id:0,
parent_id: 0,
},
{
comment_id: 5,
comment_pr_id: 1,
comment_user_name: '九月',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "学习学习",
comment_time: '2019年3月20日',
reply_id: 0,
parent_id: 0,
},
],
//回复数据
comment_list2: [
{
comment_id: 2,
comment_pr_id: 1,
comment_user_name: '九月时',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "谢谢",
comment_time: '2019年3月20日',
reply_id: 1, //
parent_id:1, //
reply_name:'' //
},
{
comment_id: 3,
comment_pr_id: 1,
comment_user_name: '四月天',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "我也想这么夸他",
comment_time: '2019年3月20日',
reply_id: 2,
parent_id: 1,
reply_name: ''
},
{
comment_id: 6,
comment_pr_id: 1,
comment_user_name: '九月时',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "你也可以跟我学学",
comment_time: '2019年3月20日',
reply_id: 2,
parent_id: 1,
reply_name: '九月'
},
{
comment_id: 7,
comment_pr_id: 1,
comment_user_name: '九月',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "不用谢,做的真是不错",
comment_time: '2019年3月20日',
reply_id: 2,
parent_id: 1,
reply_name: '九月时'
},
{
comment_id: 8,
comment_pr_id: 1,
comment_user_name: '九月时',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "你们也太会拍马屁了",
comment_time: '2019年3月20日',
reply_id: 2,
parent_id: 1,
reply_name: '四月天'
},
{
comment_id: 9,
comment_pr_id: 1,
comment_user_name: '九月时',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "那就跟我好好学",
comment_time: '2019年3月20日',
reply_id: 5,
parent_id: 5,
reply_name: ''
},
{
comment_id: 10,
comment_pr_id: 1,
comment_user_name: '九月',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "是的,你是大佬啊",
comment_time: '2019年3月20日',
reply_id: 9,
parent_id: 5,
reply_name: '九月时',
},
],
第二部分:wxml页面实现数据显示:
<view class="cu-list menu menu-avatar comment solids-top">
<block wx:for="{{comment_list}}" wx:for-index="index" wx:for-item="clist" wx:key>
<view class="cu-item" wx:if="{{clist.reply_id == 0}}"> //显示评论列表
<view class="cu-avatar round" style="background-image:url({{clist.comment_user_avatar}});"></view>
<view class='content'>
<view class='text-grey'>{{clist.comment_user_name}}</view>
<view class='text-gray text-content text-df margin-top-xs' bindtap='replyComment' data-name='{{clist.comment_user_name}}' data-cid='{{clist.comment_id}}' data-type="1" data-pid="{{clist.comment_id}}">
{{clist.comment_text}}
</view>
<block wx:for="{{comment_list2}}" wx:key wx:for-index="c2" wx:for-item="clist2"> //循环回复列表
<view class='bg-grey text-sm padding-as' wx:if="{{clist2.parent_id==clist.comment_id}}"> //判断回复列表的parent_id是不是跟回复列表的一致
<view class="flex" bindtap='replyComment' data-name='{{clist2.comment_user_name}}' data-cid='{{clist2.comment_id}}' data-type="2" data-pid="{{clist2.parent_id}}">
<view wx:if="{{clist2.reply_name.length>0}}">{{clist2.comment_user_name}} 回复 {{clist2.reply_name}}:</view> //这里是回复的名字
<block wx:else>
<view>{{clist2.comment_user_name}}:</view>
</block>
<view class='flex-sub'>{{clist2.comment_text}}</view>
</view>
</view>
</block>
<view class='margin-top-sm flex justify-between'>
<view class='text-gray text-df'>{{clist.comment_time}}</view>
</view>
</view>
</view>
</block>
</view>
js方法:replyComment:
replyComment:function(e){
var id = e.currentTarget.dataset.cid
console.log(id)
var name = e.currentTarget.dataset.name
var type = e.currentTarget.dataset.type
var parent_id = e.currentTarget.dataset.pid
console.log(parent_id)
this.setData({
now_reply:id,
now_reply_name: name,
now_reply_type: type,
now_parent_id:parent_id,
focus:true,
placeholder: '回复' + name+":"
})
},
上面基本上就是评论的实现部分了。当然,完整的效果还离不开,下面那个发送按钮的操作,我这里也说一下。
第三部分:发送评论,完整实现评论效果
下面那个发送框加,发送按钮也是colorUI中的,你能找到的源码的,贴一下:
<view class="cu-bar foot input">
<view class="cu-avatar round" style="background-image:url({{userinfo.avatarUrl}});"></view>
<view class='action'>
<text class='icon-roundaddfill text-grey'></text>
</view>
<input class='solid-bottom' value="{{comment_text}}" placeholder='{{placeholder}}' maxlength="300" cursor-spacing="10" focus="{{focus}}" bindblur="onReplyBlur" bindinput='getCommentText'></input>
<view class='action'>
<text class='icon-emojifill text-grey'></text>
</view>
<button class='cu-btn bg-green shadow-blur' bindtap='sendComment'>发送</button>
</view>
js代码:onReplyBlur,onReplyBlur,getCommentText,sendComment
getCommentText: function (e) {
var val = e.detail.value;
this.setData({
comment_text: val
});
},
onReplyBlur: function (e) {
var that = this;
const text = e.detail.value.trim();
if (text === '') {
that.setData({
now_reply: 0,
now_reply_name:null,
now_reply_type:0,
now_parent_id:0,
placeholder: "就不说一句吗?",
focus:false
});
}
},
sendComment:function(e){
var that= this
var comment_list = that.data.comment_list //获取data中的评论列表
var comment_list2 = that.data.comment_list2 //获取data中的回复列表
var comment_text = that.data.comment_text //获取当前的评论幸喜
var userinfo = that.data.userinfo //获取当前的用户信息
var comment_user_name = userinfo.nickName //用户昵称
var comment_user_avatar = userinfo.avatarUrl //用户头像
var timestamp = Date.parse(new Date()); //时间戳
var create_time = common.timetrans(timestamp) //格式化时间戳
var reply_id = that.data.reply_id //获取回复的评论id
console.log(timestamp)
console.log(create_time)
var comment_list_length = comment_list.length //获取当前评论数组的长度
console.log("当前评论数组的长度" + comment_list_length)
var last_id = comment_list[comment_list_length -1].comment_id //获取最后一个的id
console.log("当前评论数组的最后一个的id" + last_id)
var comment_list2_length = comment_list2.length //获取当前回复数组的长度
console.log("当前评论数组的长度" + comment_list2_length)
var last_id2 = comment_list2[comment_list2_length - 1].comment_id //获取回复一个的id
console.log("当前评论数组的最后一个的id" + last_id2)
var new_id = last_id > last_id2 ? last_id + 1 : last_id2 + 1
console.log("新的id是"+new_id)
var reply_name = null
var parent_id = 0
var reply_id = that.data.now_reply
console.log("回复的id是" + reply_id)
if (reply_id!=0){
console.log("现在是回复")
var reply_type = that.data.now_reply_type
parent_id = that.data.now_parent_id
console.log("回复的所属的parent_id是" + parent_id)
console.log("回复的类型是" + reply_type)
if (parent_id > 0) {
if (reply_type == 1){
parent_id = reply_id
console.log("现在是回复评论")
}else{
reply_name = that.data.now_reply_name
console.log("现在是再回复" + reply_name+"的回复")
}
}
}else{
console.log("现在是评论" )
}
var comment_detail = {}
comment_detail.comment_id = new_id
comment_detail.comment_user_name = comment_user_name
comment_detail.comment_user_avatar = comment_user_avatar
comment_detail.comment_text = comment_text
comment_detail.comment_time = create_time
comment_detail.reply_id = reply_id
comment_detail.parent_id = parent_id
comment_detail.reply_name = reply_name
console.log(comment_detail)
if (comment_detail.parent_id>0){
comment_list2.push(comment_detail)
}else{
comment_list.unshift(comment_detail)
}
that.setData({
comment_text:null,
now_reply: 0,
now_reply_name: null,
now_reply_type: 0,
now_parent_id: 0,
placeholder: "就不说一句吗?",
comment_list,
comment_list2
},()=>{
//这里写你访问后台插入数据库的代码
})
},
最后完整的贴一下js中data的数据:因为有些数据你不定义一个初始值,有时候会报undefined错误,最好在data中设置一下。
data: {
isCard: true,
like_list:[
{
user_id:1,
user_name:'随手一赞',
user_avatar:'https://image.weilanwl.com/img/square-2.jpg'
},
{
user_id: 2,
user_name: '随手一赞',
user_avatar: 'https://image.weilanwl.com/img/square-2.jpg'
},
{
user_id: 3,
user_name: '随手一赞',
user_avatar: 'https://image.weilanwl.com/img/square-2.jpg'
},
{
user_id: 4,
user_name: '随手一赞',
user_avatar: 'https://image.weilanwl.com/img/square-2.jpg'
},
{
user_id: 5,
user_name: '随手一赞',
user_avatar: 'https://image.weilanwl.com/img/square-2.jpg'
},
],
comment_list:[
{
comment_id:1,
comment_pr_id:1,
comment_user_name:'九月',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text:"做的不错嘛",
comment_time:'2019年3月20日',
reply_id: 0,
parent_id: 0,
},
{
comment_id: 4,
comment_pr_id: 1,
comment_user_name: '九月',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "可以可以",
comment_time: '2019年3月20日',
reply_id:0,
parent_id: 0,
},
{
comment_id: 5,
comment_pr_id: 1,
comment_user_name: '九月',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "学习学习",
comment_time: '2019年3月20日',
reply_id: 0,
parent_id: 0,
},
],
comment_list2: [
{
comment_id: 2,
comment_pr_id: 1,
comment_user_name: '九月时',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "谢谢",
comment_time: '2019年3月20日',
reply_id: 1,
parent_id:1,
reply_name:''
},
{
comment_id: 3,
comment_pr_id: 1,
comment_user_name: '四月天',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "我也想这么夸他",
comment_time: '2019年3月20日',
reply_id: 2,
parent_id: 1,
reply_name: ''
},
{
comment_id: 6,
comment_pr_id: 1,
comment_user_name: '九月时',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "你也可以跟我学学",
comment_time: '2019年3月20日',
reply_id: 2,
parent_id: 1,
reply_name: '九月'
},
{
comment_id: 7,
comment_pr_id: 1,
comment_user_name: '九月',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "不用谢,做的真是不错",
comment_time: '2019年3月20日',
reply_id: 2,
parent_id: 1,
reply_name: '九月时'
},
{
comment_id: 8,
comment_pr_id: 1,
comment_user_name: '九月时',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "你们也太会拍马屁了",
comment_time: '2019年3月20日',
reply_id: 2,
parent_id: 1,
reply_name: '四月天'
},
{
comment_id: 9,
comment_pr_id: 1,
comment_user_name: '九月时',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "那就跟我好好学",
comment_time: '2019年3月20日',
reply_id: 5,
parent_id: 5,
reply_name: ''
},
{
comment_id: 10,
comment_pr_id: 1,
comment_user_name: '九月',
comment_user_avatar: 'https://image.weilanwl.com/img/square-2.jpg',
comment_text: "是的,你是大佬啊",
comment_time: '2019年3月20日',
reply_id: 9,
parent_id: 5,
reply_name: '九月时',
},
],
comment_text: null,
reply_id:0,
placeholder:'就不说一句吗?',
reply_id:0,
now_reply_name:null,
type:0,
now_parent_id:0,
now_reply:0
},
如果有不懂的,可下方留言询问。