javascript - 嵌套组件无法正确重新渲染 : VueJs

标签 javascript vue.js

我是 Vue 新手,我正在构建这个论坛之类的东西,可以在其中添加嵌套评论。这里有两个组件。发表论坛和评论。 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>

最佳答案

我已经尝试过这个:

此代码只是一个可能对您有所帮助的示例。就我而言, child 组件在您的情况下是 comment 组件,每个 child 组件都有自己的 @action他的组件的监听器。因此,他可以用它来修改自己的 child

以下是codesandbox 上的示例:https://codesandbox.io/s/qzrp4p3qw9

父组件

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

子组件

<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.parent"></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);
        }
    }
}

关于javascript - 嵌套组件无法正确重新渲染 : VueJs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52551840/

相关文章:

vue.js - 如何将值从 Vue 数据传递给 href?

gulp - vueify(在 gulp 任务中)与 vue 文件的 babel 转换

javascript - nuxt js 中的异步组件延迟

javascript - 将值传递给构造函数时使构造函数正常工作的问题

javascript - 单击一个时切换/关闭所有其他 div

javascript - 通量 + react : when to keep state of visual components at store

docker - 如何将环境变量从docker-compose传递到项目?

javascript - Angular2 阻止在指令中按下回车键时提交表单

javascript - 相对于另一个元素定位下一个元素

javascript - 如何在 Vue js 中解析 json 以在模板中使用它