我有一个非常奇怪的情况,即子组件prop
中的更改未触发重新渲染。
这是我的设置。在我的父母:
<child :problemProp="proplemPropValue""></child>
在孩子中我定义了道具:
{
name: "Child",
props: {
problemProp: {
type: [File], //yes it is a file
required: true
}
}
然后我尝试渲染它(仍然在子组件中)
<template>
<div id="dropzone-preview" class="file-row">
{{problemProp}} <--This should just show the prop as a JSON string-->
</div>
</template>
最初正确呈现。但problemProp
有一个属性upload.progress
,当我在父级中更改它时(我可以确认它在父级上发生了变化),它在子级中不会发生变化。
如果我现在向孩子添加第二个道具dummyProp
:
{
name: "Child",
props: {
problemProp: {
type: [File], //yes it is a file
required: true
},
dummyProp: {
type: Number
}
}
现在,当dummyProp
发生变化时,propblemProp
也会发生变化。这里发生了什么?为什么dummyProp
中的更改强制重新呈现,但propblemProp
中的更改不会?
答案 0 :(得分:2)
问题的根源似乎是当您向阵列添加File对象时,Vue 将失败将其转换为观察值。这是因为Vue ignores browser API objects:
对象必须是普通的:本机对象,例如浏览器API对象 和原型属性被忽略。
在这种情况下,对该对象的任何更改都不会自动反映在Vue中(正如您通常所期望的那样),因为Vue不知道它们已更改。这也是您更新dummyProp
时似乎有效的原因,因为观察到该属性的更改并触发重新渲染。
那么,该怎么做。通过对addedFile
方法进行一些小改动,我已经能够让你的垃圾箱工作了。
addedfile(file){
console.log(file);
self.problemPropValues.push(Object.assign({}, file));
},
首先,您不需要(或想要)使用$data
,只需直接引用该属性即可。其次,通过使用Object.assign
制作副本,Vue可以正确观察对象,并且更新现在会反映在子节点中。根据您的使用情况,可能是您需要在某些时候使用深层复制方法而不是Object.assign
的情况,但是现在这看起来有效。
Here is the code我最终让bin工作(转换为codepen因为我发现更容易使用codepen)。