In the app I am working on we have many modals, each modal contains a small amount of data, generally 2-3 fields, sometimes checkboxes, lists etc.
The question is how do reset/destroy the component from the inside when it is closed. The reason for this would be twofold:
1) Not to have to clear individual data fields on each modal.
2) Watchers on props would be triggered again when the modal is opened a second time (some of the modals are "edit" and therefore are prepopulated, I would rather not manage this data).
Now if the modal was closed from the outside then I could change the key on the component and this would solve the issue, since the modal is closed from inside a component, then I do not know if I can do this (would be great).
How do you setup your modals? What would be clean architecture?
Example code:
<parentComp>
<customChildModal ref="$customChildModal"></customChildModal>
</parentComp>
// customChildModal
<v-dialog v-model="dialogState">
<v-text-field v-model="name">
...
</v-text-field>
<v-btn @click="dialogState = false">Cancel</v-btn>
<v-btn @click="saveSomething">Save</v-btn>
...
data(){
return {
dialogState: false,
name: ''
...
Now in some cases I actually have many fields and I need them to clear each time the modal is closed. This needs to cover cases where "Cancel" is clicked, as well as where the user clicks outside the modal or the ESC key which I support.
To create and destroy the component I believe you have to use v-if. But unfortunately it not easy with v-dialog due to the transition.
The first solution, use v-dialog inside parent instead of child:
Parent:
<v-btn @click.stop="dialog = true">Open Dialog</v-btn>
<v-dialog v-model="dialog">
<!-- transition component help to keep leave transition -->
<transition :duration="300">
<Child v-if="dialog"/>
</transition>
</v-dialog>
Child:
<v-btn @click="$parent.dialog = false">Disagree</v-btn>
Example
The second solution, use v-dialog inside child
Parent:
<v-btn @click.stop="dialog = true">Open Dialog</v-btn>
<Child v-if="dialog" @close="dialog = false"/>
Child:
<v-dialog v-model="dialog" @click:outside='close'>
<v-btn @click="close">Disagree</v-btn>
</v-dialog>
{
mounted() {
this.dialog = true
},
methods: {
close() {
this.dialog = false
setTimeout(() => { // again this help to keep transition
this.$emit('close')
}, 300)
}
}
}
Example
I think both solutions are correct in different point of view. But I prefer the first solution since it has less footprint.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With