In Vue/Vuetify, how do we hide/show dialogs from parent? I'm trying to use v-model
and here is a simplified version of my setup:
Parent component (just a button that triggers the child component to show)
<template>
<div>
<v-btn class="ma-2" outlined fab color="red" small @click.stop="editItem()">
<v-icon size="16">mdi-close-circle</v-icon>
</v-btn>
<user-dialog v-model="dialog" :eitem="editedItem" class="elevation-2" />
</div>
</template>
<script>
import UserDialog from "./UserDialog.vue";
export default {
components:{
UserDialog
},
data() {
return {
counter: 0,
dialog: false,
editedItem: {},
}
},
methods: {
editItem: function() {
this.counter++;
this.editedItem = Object.assign({}, {
title: 'some title' + this.counter,
details: 'some details for this item'
});
this.dialog = true;
},
},
}
</script>
Child component (basically a dialog box)
<template>
<v-dialog v-model="value" max-width="500px">
<v-card>
<v-card-title>
<span class="headline">A Dialog</span>
</v-card-title>
<v-card-text>
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12>
<v-text-field v-model="eitem.title" label="Title"></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field v-model="eitem.details" label="Details"></v-text-field>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click.stop="save">Save</v-btn>
<v-btn color="blue darken-1" text @click.stop="close">Cancel</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
value: Boolean,
eitem: Object,
},
data() {
return {
editedItem: this.eitem,
}
},
methods: {
save() {
//perform save
this.$emit('input', false);
},
close() {
this.$emit('input', false);
},
},
}
</script>
This setup works, but give the following warning:
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"
But if act upon this advice and declare a data
item in the child component and set v-model
of the v-dialog
to this data item, the dialog stops showing up upon click.
I perhaps understand why it does that, but cannot figure out a proper way of fixing this that doesn't show warnings. Can anyone help me with this?
v-model
bind thev-text-field
's value to the prop. And oninput
emit a custom event to the parent and let it update the prop's value. You can use a computed property with a getter/setter. – Husam Ibrahimv-model
is a syntactic sugar that does exactly the thing that you described. How'd that approach be different? – dotNETv-dialog
'sv-model
at the moment. The gist of the problem in my understanding is that I need a way to bind a localdata
item with aprop
, so that whenever the parent component changes its bound data item, the child component is notified about this change and in response the child component updates its local data item (which will then trigger v-dialog to appear or disappear.. – dotNETv-model
will attempt to directly modify the value on input and that's the equivalent of@input="value=$event.target.value"
. What you want is to emit a custom event to the parent via@input="()=>{$emit('updateValue', newValue}"
and have the parent listen for anupdateValue
event to update the value of the prop. That will automatically be reflected in the child component after update. – Husam Ibrahimvalue
as a prop to be used withv-dialog
but you don't pass it's value from the parent. In that case you should specify a default value. And instead of usingv-model
on the value directly use a computed property with a getter/setter. That way if a value is passed from the parent you can emit a custom event to the parent to update the prop's value. Otherwise you can update a local value instead. – Husam Ibrahim