我需要实现一个评论回复功能,任何人可以回复   (评论和评论的回复),如下图:

在递归显示回复的时候我遇到了问题,我需要在显示每一条回复的时候判断它是否有子回复

 用vue实现评论的渲染,评论数据如下:

data:{
                commentList:[
                    {
                        "Id":"1",
                        "author":"mldwyy",
                        "created_at":"2019-2-2",
                        "content":"我是评论我是评论评论评论1",
                        "reply":
                            [
                                {
                                    "id":"0",
                                    "author":"mldwyy",
                                    "created_at":"2019-2-3",
                                    "content":"hello to go to the to go to the 我在回复mldwyy的1,我是2",
                                    "reply":[{
                                        "id":"18",
                                        "author":"reply",
                                        "created_at":"2019-2-3",
                                        "content":"hello to go to the to go to the 我是回复mldwyy的2,我是3",
                                        "reply":[
                                            {
                                                "id":"5",
                                                "author":"reply",
                                                "created_at":"2019-2-3",
                                                "content":"hello to go to the to go to the 我回reply的3,我是4"
                                            }
                                        ]
                                    },
                                        {
                                            "id":"2",
                                            "author":"reply",
                                            "created_at":"2019-2-3",
                                            "content":"hello to go to the to go to the 我回复mldwyy的2,我是5"
                                        },
                                    ],
                                },
                                {
                                    "id":"10",
                                    "author":"reply",
                                    "created_at":"2019-2-3",
                                    "content":"我是mldwyy的1,我是6"
                                },
                            ],
                    },
                    {
                        "id":"11",
                        "author":"mldwyy二二",
                        "created_at":"2019-2-2",
                        "content":"我是第二条评论我是第二条7",
                        "reply":
                            [
                                {
                                    "id":"7",
                                    "author":"mldwyy",
                                    "created_at":"2019-2-3",
                                    "content":"我是mldwyy二二二的7回复,我是8"
                                },
                                {
                                    "id":"90",
                                    "author":"reply",
                                    "created_at":"2019-2-3",
                                    "content":"我是mldwyy二二二的7回复,我是9"
                                },
                            ],
                    },
                    {
                        "id":"67",
                        "author":"mldwyy三三",
                        "created_at":"2019-2-2",
                        "content":"我是第三条评论我是第三条10",
                        "reply":
                            [
                            ],
                    }
                ],
            },

显然要把这些数据全部显示在页面上光凭一个v-for和v-if是无法实现的 。我的做法是定义一个模板,然后进行模板的递归调用,模板定义如下

components:{
                mycom:{
                    name:"mycom",
                    template:'#replyy',
                    props:['parmsg','index'],
                    methods: {
                        showInput:function(j,father) {
                            //alert(j);
                            var lists=document.getElementsByClassName("writeBack");
                            for(var i=0;i<lists.length;i++){
                                lists[i].style.display='none';
                            }
                            this.display='block';
                            document.getElementById("back"+j).style.display=this.display;
                            this.$emit('fun',father);
                        },
            }
}
<template id="replyy">
        <div>{{-- 此处需要注意模板里面只能有一个根结点,所以必须用大div包起来(!!!此处大坑,没有被包起来会报Error compiling template:- Cannot use v-for on stateful component root element because it renders multiple elements. 以及Multiple root nodes returned from render function. Render function should return a //single root node.)--}}
            <div class="back" style="margin: 0" v-for="(item,i) in parmsg" :key="i">//子组件渲染父组件传来的回复列表
                <div>
                    <div class="panel" style="box-shadow:none;border-top: 1px solid rgba(0,0,0,0.05);padding-top: 5px">@{{ item.author }}回复:
                        <a style="float: right;margin-left: 10px" href="#"><strong>删除</strong></a> <p class="huiFu" @click="showInput(index,item.id)"><strong>回复</strong></p>
                    </div>
                    <div class="panel-body">@{{ item.content}}<p style="text-align: right">@{{ item.created_at }}</p>
                    </div>
                </div>
                //子组件(回复处)判断该回复是否还有回复,如果有再次调用子组件,并把这条回复的reply(即item.reply)传给接下来的子组件供其渲染
                <mycom v-if="item.reply" :parmsg="item.reply" :index="i"></mycom>
            </div>
        </div>
    </template> 

调用子组件处代码:

 <div class="panel panel-default" v-for="(item,i) in commentList" :key="i">
                    <div class="panel-heading">@{{i+1}}楼:@{{ item.author }}<a style="float: right;margin-left: 10px" href="/comment/del"><strong>删除</strong></a> <p class="huiFu" style="float: right"  @click="showInput(i,item.id)"><strong>回复</strong></p></div>
                    <div class="panel-body">@{{ item.content }}<p style="text-align: right">@{{ item.created_at }}</p></div>
                    //父组件判断评论是否有reply,如果有则调用子组件
                    <mycom v-if="item.reply" :parmsg="item.reply" :index="i"></mycom>
                    <div class="writeBack" style="display: none" :id="getId(i)">
                        <textarea rows="4"></textarea>
                        <div class="panel-body" style="text-align: right"><button class="btn btn-primary" style="text-align: right"  @click="replyComment">确定</button></div>
                    </div>
                </div>

最终结果:

Logo

前往低代码交流专区

更多推荐