Reputation: 13413
I am trying to break this code [A] (see fiddle at bottom):
<div class="q-uploader-files scroll">
<q-item
v-for="file in files"
:key="file.name"
>
<q-progress :percentage="file.__progress"/>
<div>
{{ file.__progress }}%
</div>
<q-item-side v-if="file.__img" :image="file.__img.src">
</q-item-side>
<q-item-side right>
<q-item-tile
:icon="file.__doneUploading ? 'mdi-done' : 'mdi-clear'"
:color="file.__doneUploading ? 'primary' : 'color'"
@click.native="__remove(file)"></q-item-tile>
</q-item-side>
</q-item>
</div>
into [B] the basically the same code but then with a child component. Here the parent:
<div class="q-uploader-files scroll">
<my-uploader-progress
v-for="file in files"
:file="file"
:key="file.name"
:color='color'
>
</my-uploader-progress>
</div>
And here the child:
<template>
<q-item>
<q-progress
:color="file.__failed ? 'negative' : 'grey'"
:percentage="file.__progress"
/>
<div>
{{ file.__progress }}%
</div>
<q-item-side v-if="file.__img" :image="file.__img.src"/>
<q-item-side v-else icon="mdi-file" :color="color"/>
<q-item-main :label="file.name" :sublabel="file.__size"/>
<q-item-side right>
<q-item-tile
:icon="file.__doneUploading ? 'mdi-done' : 'mdi-clear'"
:color="file.__doneUploading ? 'primary' : 'color'"
@click.native="__remove(file)"
/>
</q-item-side>
</q-item>
</template>
On the child I have set the file
property:
props: {
file: {
type: File,
required: true
}
},
Somehow in the parent-child code there must be a problem as the file
__img property does not exist in the child (at render) in [B] see:
, whereas it does exist in [A]:
What's wrong? There are no errors in the console.
The original ([A]) code is from here. The File Object consists of a xhr instance (I suppose?!).
Here fiddles/ sandboxes for [A] and for [B]. Press ADD and select an image to upload, it will not upload but [A] will show its thumbnail img etc; do the same for [B] and these will not show.
NOTA BENE: I noticed that the file.__img
does not show first in [B], but when I start editing code in the child component..., it suddenly SHOWS. So apparently/ maybe it is something asynchronous and after a render-refresh it is there...?!
Upvotes: 8
Views: 2482
Reputation: 7187
If you're looking for a working solution you can simply assign a key to the my-uploader-progress
component based on the presence of an __img
property, which will force it to re-render when the property becomes available ..
<my-uploader-progress
v-for="file in files"
:file="file"
:key="file.__img ? '1-' + file.name : '0-' + file.name"
:hide-upload-progress="hideUploadProgress"
:color='color'
>
</my-uploader-progress>
Upvotes: 5
Reputation: 5465
You have to make the property value reactive by returning a factory function.
props: {
file: {
type: File,
required: true,
default: function () {
return {
name: '',
_progress: 0
}
}
}
},
Upvotes: 5
Reputation: 875
If you are updating the property value of an object in props after the child has been mounted it wont work, you would have to replace the complete object to make it work,
Upvotes: 4
Reputation: 1195
Sort of an ugly hack, but I hope this will fix the issue. Try setting a timeout in the mounted function to buy some time before the file gets loaded and then true the v-if
condition to load image element in the DOM.
<template>
<q-item-side v-if="file_loaded" :image="file.__img.src"/>
</template>
<script>
data () {
file_loaded: false
},
mounted() {
setTimeout(() => {
this.file_loaded = true
}, 1000)
}
</script>
I have tried this in your sandbox [B] and it's working fine.
Upvotes: 4