儿童道具不更新,即使父母也这样做

时间:2017-09-16 17:42:11

标签: javascript vue.js vuejs2 vue-component

我有一个非常奇怪的情况,即子组件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中的更改不会?

1 个答案:

答案 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)。