先看需求
::: hljs-center
:::
我们需要将评论数据进行渲染成如图所示,后端给我们返回的数据格式又是啥样的呢?答案就是一级一级的父子层级嵌套的数据结构:
::: hljs-center
:::
面对这样的数据结构,我们怎么渲染呢?
通过递归的形式渲染就比较可行
首先,我们创建一个回复评论的组件,父组件中将评论的回复数组传给子组件,在子组件中进行渲染,如果回复的数组中还有子回复那么这时候把数据传给回复组件即可。这样就能达到递归渲染数组的目的了。
引用回复组件
在父组件中引用回复组件
import replyComment from '../comment-item/comment-item.vue'
components: {replyComment},
<!-- 回复 -->
<replyComment style="padding-left: 68rpx;" :commentChildren="item.children" @child_up="handleCommentUp"
@child_down="handleCommentDown" @child_reply="handleCommentInputPopupShow"></replyComment>
回复组件
replyComment:
<template>
<view class="reply-content-wrapper">
<view class="comment-reply-data" v-for="(item,index) in commentChildren" :key="index">
<view class="comment-reply-user">
<view class="comment-root-header flex-row">
<image :src="item.criticImg" mode=""></image>
<view class="username">
{{item.criticName}}
</view>
</view>
<view class="replycomment-content">
<text> 回复 </text><text class="replyer">{{item.reCriticName}}</text>
<text>{{item.comment}}</text>
</view>
<view class="comment-data flex-row-space">
<view class="create-time">
{{formatDate(item.createTime)}}
</view>
<view class="operation-icon flex-row">
<view class="operation-item">
<i class="icon iconzan_before" @tap="handleCommentUp(item.id)"></i>
<text>{{item.supportCount}}</text>
</view>
<view class="operation-item">
<i class="icon iconcai_before" @tap="handleCommentDown(item.id)"></i>
<text>{{item.opposeCount}}</text>
</view>
<view class="operation-item">
<i class="icon iconpinglun" @tap="handleCommentInputPopupShow(item)"></i>
</view>
</view>
</view>
</view>
<replyComment v-if="item.children" :commentChildren="item.children" @child_up="handleCommentUp" @child_down="handleCommentDown"
@child_reply="handleCommentInputPopupShow"></replyComment>
</view>
</view>
</template>
<script>
import {formateTime} from '../../utils/index.js'
export default {
name: 'replyComment',
props: {
commentChildren: {
type: Array,
default: []}
},
data() {return {};
},
methods: {
// 格式化时间
formatDate(time) {if (!time) {return ''}
return formateTime(time)
},
handleCommentUp(id) {this.$emit('child_up', id)
},
handleCommentDown(id) {this.$emit('child_down', id)
},
handleCommentInputPopupShow(item) {this.$emit('child_reply', item)
},
}
}
</script>
<style lang="less" scoped>
.comment-reply-data {
.comment-root-header {
color: #333333;
margin: 27rpx 0;
image {
width: 48rpx;
height: 48rpx;
border-radius: 40rpx;
margin-right: 20rpx;
}
}
.comment-root-user {border-bottom: 2rpx solid #eee;}
image {
width: 48rpx;
height: 48rpx;
border-radius: 40rpx;
margin-right: 20rpx;
}
.replycomment-content {
margin-bottom: 20rpx;
word-break: break-all;
.replyer {
display: inline-block;
padding: 0 12rpx;
color: #333333;
position: relative;
bottom: 2rpx;
}
}
.comment-data {
color: #666;
line-height: 20rpx;
font-size: 20rpx;
padding-bottom: 28rpx;
border-bottom: 2rpx solid #EDEDED;
.operation-icon {
.operation-item {
margin-left: 49rpx;
.icon {font-size: 22rpx;}
}
}
// 点赞
.active-support {
animation-name: support;
animation-duration: 500ms;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
}
}
</style>
那么实际效果呢?
::: hljs-center
:::
其实,刚开始看到这个数据结构十分头疼,后来仔细想想递归是能够解决的,然后就开始动手,没想到真就实现了。开发中我们可能会遇到各种需求,只要冷静下来好好想想,总能找到解决办法的。
老铁们可以关注我的个人公众号
也可以去我的博客瞅瞅