嵌套的组件无法正确重新渲染:VueJ

时间:2018-09-28 09:02:37

标签: javascript vue.js

我是Vue的新手,我正在构建这种可在其中添加嵌套评论的东西。在这里有两个部分。 PostForum和评论。 PostForum包含一个输入框和父注释。在每个评论中,我都递归添加了子评论。

当我添加评论时,它可以正常工作。但是在删除时,它将发送ajax请求,但是没有重新渲染。 这就是我的设计方式。删除评论时,我发出一个全局事件,并在PostForum组件中侦听该事件并从其数据中删除该评论。那么,这是否应该相应地重新渲染所有评论?有人可以告诉我我在做什么错吗?

PostForum.vue

<template>
  <!-- comment box here -->

  <comment
    v-for="(comment, index) in comments" 
    v-if="!comment.parent_id"
    :reply="true" 
    :initialChildren="getChildren(comment.id)" 
    :key="index" 
    :comment="comment">
  </comment>
</template>

<script>
export default {
  data () {
    return {
      comments: [], // all comments
        comment: { // new comment [at comment box]
            body: '',
            parent_id: 0,
        },
    }
  },
  methods: {
    deleteComment (node) {
        axios.delete(`/comments/${node.id}`)
            .then(res => {
                this.comments.splice(node.key, 1)
            })
            .catch(err => {
                console.log(err)
            })
    },
    getChildren: function (parent_id) {
        return this.comments.filter(child => parent_id == child.parent_id)
    },
  },
  mounted: function () {
    window.Event.$on('comment-deleted', (node) => this.deleteComment(node))
  }
}
</script>

Comment.vue

<template>
  <button @click="deleteComment">X</button>

  <!-- comment body goes here -->

  <comment v-for="(child, i) in children" :key="i" :reply="false" :comment="child"></comment>

  <!-- reply form here -->
</template>

<script>
export default {
  props: ['initialChildren']
  data: function () {
    return {
        newComment: {
            body: '',
            parent_id: this.comment.id,
        },
        children: this.initialChildren,
    }
  },
  methods: {
    deleteComment () {
        window.Event.$emit('comment-deleted', {key: this.$vnode.key, id: this.comment.id})
    },
  }
}
</script>

1 个答案:

答案 0 :(得分:2)

我已经尝试过了:

此代码仅是一个示例,可能会对您有所帮助,就我而言,child组件就是您的案例中的comment组件。

,并且每个child组件都有自己的@action组件的child侦听器。因此他可以用它来修改自己的childrens

此处是在codeandbox上的示例:https://codesandbox.io/s/qzrp4p3qw9

ParentComponet

<template>
    <div>
        <Child v-for="(children,index) in childrens" :child="children" :key="index" :parent="0" :pos="index"></Child>
    </div>
</template>
import Child from './child'; 
export default {
    data() {
        return {
            childrens:[
                {
                    name:"a",
                    childrens:[
                        {
                            name:'aa',
                        },
                        {
                            name:'ba',
                            childrens:[
                                {
                                    name:'baa',
                                    childrens:[
                                        {
                                            name:'baaa',
                                        },
                                        {
                                            name:'baab',
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                },
                {
                    name:"a",
                    childrens:[
                        {
                            name:'aa',
                        },
                        {
                            name:'ab',
                            childrens:[
                                {
                                    name:'aba',
                                    childrens:[
                                        {
                                            name:'abaa',
                                            childrens:[
                                                {
                                                    name:'baa',
                                                    childrens:[
                                                        {
                                                            name:'baaa',
                                                        },
                                                        {
                                                            name:'baa',
                                                        }
                                                    ]
                                                }
                                            ]
                                        },
                                        {
                                            name:'abab',
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    },
    components:{
        Child
    }
}

ChildComponent

<template>
    <div>
        <div style="padding:5px">
            {{ child.name }}
            <button @click="deleteComment(child)">x</button>
        </div> 
        <child @delete="deleteSubComment" style="padding-left:15px" v-if="typeof child.childrens !== 'undefined'" v-for="(children,index) in child.childrens" :child="children" :pos="index" :key="index" :parent="children.parend"></child>
    </div>
</template>
export default {
    name:"child",
    props:['child','parent',"pos"],
    methods:{
        deleteComment(child) {
            this.$emit('delete',child);
        },
        deleteSubComment(obj) {

            this.child.childrens.splice(this.child.childrens.indexOf(obj),1);
        }
    }
}