共计 3004 个字符,预计需要花费 8 分钟才能阅读完成。
先看需求
::: 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
:::
其实,刚开始看到这个数据结构十分头疼,后来仔细想想递归是能够解决的,然后就开始动手,没想到真就实现了。开发中我们可能会遇到各种需求,只要冷静下来好好想想,总能找到解决办法的。
老铁们可以关注我的个人公众号
也可以去我的博客瞅瞅
正文完
发表至: javascript
2020-06-24