嵌套组件无法正确重新渲染:VueJs [英] Nested components not re-rendering properly: VueJs
问题描述
我是 Vue 的新手,我正在构建这种可以在其中添加嵌套评论的论坛.这里有两个组件.PostForum 和评论.PostForum 包含一个输入框和父评论.在每条评论中,我递归地添加子评论.
当我添加评论时,它工作正常.但是在删除时,它会发送 ajax req 但没有重新渲染.所以这就是我设计它的方式.删除评论时,我会发出一个全局事件,在 PostForum 组件中,我会侦听该事件并从其数据中删除该评论.那么这不应该相应地重新呈现所有评论吗?谁能告诉我我在这里做错了什么?
PostForum.vue
<!--这里的评论框--><评论v-for="(comment, index) 在评论中"v-if="!comment.parent_id":回复=真":initialChildren="getChildren(comment.id)":key="索引":comment="评论"></评论></模板><脚本>导出默认{数据 () {返回 {评论:[],//所有评论评论:{//新评论 [在评论框]身体: '',parent_id: 0,},}},方法: {deleteComment(节点){axios.delete(`/comments/${node.id}`).then(res => {this.comments.splice(node.key, 1)}).catch(错误 => {控制台日志(错误)})},getChildren:函数(parent_id){返回 this.comments.filter(child => parent_id == child.parent_id)},},挂载:函数(){window.Event.$on('comment-deleted', (node) => this.deleteComment(node))}}
Comment.vue
<button @click="deleteComment">X</button><!-- 评论正文在这里--><comment v-for="(child, i) in children" :key="i" :reply="false" :comment="child"></comment><!-- 在这里回复表单--></模板><脚本>导出默认{道具:['initialChildren']数据:函数(){返回 {新评论:{身体: '',parent_id: this.comment.id,},儿童:this.initialChildren,}},方法: {删除评论(){window.Event.$emit('comment-deleted', {key: this.$vnode.key, id: this.comment.id})},}}
我已经试过了:
此代码只是一个可以帮助您的示例.在我的例子中, child
组件就是你的 comment
组件,每个 child
组件都有自己的 @action
他的 child
组件的监听器.所以,他可以用它来修改自己的children
.
这是关于代码和框的示例:https://codesandbox.io/s/qzrp4p3qw9
父组件
<div><Child v-for="(children,index) in childs" :child="children" :key="index" :parent="0" :pos="index"></Child>
</模板>
import Child from './child';导出默认{数据() {返回 {孩子们的:[{名称:"a",孩子们的:[{名称:'aa',},{名称:'ba',孩子们的:[{名称:'baa',孩子们的:[{名称:'baaa',},{name:'baab',}]}]}]},{名称:"a",孩子们的:[{名称:'aa',},{名称:'ab',孩子们的:[{名称:'aba',孩子们的:[{名称:'abaa',孩子们的:[{名称:'baa',孩子们的:[{名称:'baaa',},{名称:'baa',}]}]},{name:'abab',}]}]}]}]}},成分:{孩子}}
子组件
<div><div style="padding:5px">{{ child.name }}<button @click="deleteComment(child)">x</button>
<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>
</模板>
export default {姓名:孩子",道具:['child','parent',"pos"],方法:{删除评论(子){this.$emit('delete',child);},deleteSubComment(obj) {this.child.childrens.splice(this.child.childrens.indexOf(obj),1);}}}
I'm new to Vue and I'm building this forum kind of thing which can add nested comments in it. In here there are two components. PostForum and Comment. PostForum contains an input box and parent Comments. And inside each comment, I added child comments recursively.
When I adding comments, It works fine. But when deleting, it sends the ajax req but there's no re-rendering. So this is how I designed it. When deleting a comment, I emit a global event and in PostForum component I listen to that event and deleting that comment from its data. So isn't that supposed to re-render all the comments accordingly? Can anyone tell me what am I doing wrong here?
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>
I've tried this:
This code is just an example that may help you. In my case, child
component is comment
component in your case, and each child
component has its own @action
listener for his child
component. So, he can use that to modify his own childrens
.
Here is an example on codesandbox: https://codesandbox.io/s/qzrp4p3qw9
ParentComponent
<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.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);
}
}
}
这篇关于嵌套组件无法正确重新渲染:VueJs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!