我遇到了一个问题,即组件无法识别属性的更改。 该组件嵌套了大约 5 层深。故障组件上方的每个组件都会以相同的机制进行更新,并且完美无瑕。 我花了一些时间来解决这个问题,但我找不到。
流程是:
到 commentSection 的所有内容都按预期更新,但是 commentList 没有收到更新通知(beforeUpdate 没有被触发)。
由于我测试了很多东西,所以我只会发布commentSection(父)和commenList(子)中的基本代码
<块引用>免责声明:这是一个没有后端的原型代码,因此典型的 API 请求是通过用户浏览器的 localStorage 解决的。
评论部分
<template>
<div id="comment-section">
<p>{{selectedTicket.title}}</p>
<comment-form :selectedTicket="selectedTicket" />
<comment-list :selectedTicket="selectedTicket" />
</div>
</template>
<script>
import CommentForm from "@/components/comment-section/CommentForm";
import CommentList from "@/components/comment-section/CommentList";
export default {
name: "CommentSection",
components: {
CommentForm,
CommentList,
},
props: {
selectedTicket: Object,
},
beforeUpdate() {
console.log("Comment Section");
console.log(this.selectedTicket);
},
updated() {
console.log("Comment Section is updated");
}
}
</script>
评论列表
<template>
<div id="comment-list">
<comment-item
v-for="comment in comments"
:key="comment.id"
:comment="comment"
/>
</div>
</template>
<script>
import CommentItem from "@/components/comment-section/CommentItem";
export default {
name: "CommentList",
components: {
CommentItem,
},
data() {
return {
comments: Array,
}
},
props: {
selectedTicket: Object,
},
methods: {
getComments() {
let comments = JSON.parse(window.localStorage.getItem("comments"));
let filteredComments = [];
for(let i = 0; i < comments.length; i++){
if (comments[i].ticketId === this.selectedTicket.id){
filteredComments.push(comments[i]);
}
}
this.comments = filteredComments;
}
},
beforeUpdate() {
console.log("CommentList");
console.log(this.selectedTicket);
this.getComments();
},
mounted() {
this.$root.$on("updateComments", () => {
this.getComments();
});
console.log("CL Mounted");
},
}
</script>
commentList 组件 的 beforeUpdate()
和 updated()
钩子没有被触发。
我想我可以通过一个传递数据的事件来解决这个问题,但为了便于理解,让我们假设它现在不是一个可行的选择。
答案 0 :(得分:0)
最好使用观察者,这样会更简单。
您可以使用计算属性而不是通过过滤设置评论的方法,该属性是反应性的,无需监视道具更新。
评论部分
<template>
<div id="comment-section">
<p>{{ selectedTicket.title }}</p>
<comment-form :selectedTicket="selectedTicket" />
<comment-list :selectedTicket="selectedTicket" />
</div>
</template>
<script>
import CommentForm from "@/components/comment-section/CommentForm";
import CommentList from "@/components/comment-section/CommentList";
export default {
name: "CommentSection",
components: {
CommentForm,
CommentList
},
props: {
selectedTicket: Object
},
methods: {
updateTicket() {
console.log("Comment section is updated");
console.log(this.selectedTicket);
}
},
watch: {
selectedTicket: {
immediate: true,
handler: "updateTicket"
}
}
};
</script>
评论列表
<template>
<div id="comment-list">
<comment-item
v-for="comment in comments"
:key="comment.id"
:comment="comment"
/>
</div>
</template>
<script>
import CommentItem from "@/components/comment-section/CommentItem";
export default {
name: "CommentList",
components: {
CommentItem
},
props: {
selectedTicket: Object
},
computed: {
comments() {
let comments = JSON.parse(window.localStorage.getItem("comments"));
let filteredComments = [];
for (let comment of comments) {
if (comment.ticketId == this.selectedTicket.id) {
filteredComments.push(comment);
}
}
// // using es6 Array.filter()
// let filteredComments = comments.filter(
// (comment) => comment.ticketId == this.selectedTicket.id
// );
return filteredComments;
}
}
};
</script>
答案 1 :(得分:0)
我发现了问题:由于 commentList 只是一个不使用 prop 中任何值的包装器,因此永远不会触发 beforeUpdate 和 updated 的钩子。 Vue Instance Chart 在这方面具有误导性。该图显示,当数据更改(然后重新渲染,然后更新)时,beforeUpdate 将始终触发,但 beforeUpdate 仅在必须重新渲染组件和父级时触发。 对象按预期更新,只是从未在子组件上触发重新渲染,因为包装器尚未重新渲染。