先看需求

::: 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

:::

其实,刚开始看到这个数据结构十分头疼,后来仔细想想递归是能够解决的,然后就开始动手,没想到真就实现了。开发中我们可能会遇到各种需求,只要冷静下来好好想想,总能找到解决办法的。

老铁们可以关注我的个人公众号

也可以去我的博客瞅瞅