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 ponent (just a button that triggers the child ponent 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 {
ponents:{
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 ponent (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 ponent re-renders. Instead, use a data or puted 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 ponent 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?
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 ponent (just a button that triggers the child ponent 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 {
ponents:{
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 ponent (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 ponent re-renders. Instead, use a data or puted 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 ponent 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?
Share Improve this question asked Jul 27, 2019 at 13:07 dotNETdotNET 35.5k28 gold badges173 silver badges274 bronze badges 7-
Instead of using
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 puted property with a getter/setter. – Husam Elbashir Commented Jul 27, 2019 at 13:15 -
@HusamIbrahim: I hear that
v-model
is a syntactic sugar that does exactly the thing that you described. How'd that approach be different? – dotNET Commented Jul 27, 2019 at 13:17 -
Just to clarify, those text-field bindings are not the issue at hand right now. I'm actually struggling with the
v-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 ponent changes its bound data item, the child ponent is notified about this change and in response the child ponent updates its local data item (which will then trigger v-dialog to appear or disappear.. – dotNET Commented Jul 27, 2019 at 13:22 -
The difference is that
v-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 ponent after update. – Husam Elbashir Commented Jul 27, 2019 at 13:28 -
I see that you declare
value
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 puted 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 Elbashir Commented Jul 27, 2019 at 13:40
2 Answers
Reset to default 5Since Vue throws a warning when you mutate props
, you should not use v-model
with props
. To handle this use the following pattern:
puted: {
propModel: {
get () { return this.value },
set (value) { this.$emit('input', value) },
},
},
Define puted
property with getter, that returns props.value
, and setter that emits input
event (that will be successfully handled in parent, since you use v-model
)
Don't forget to chage your template
:
<v-dialog v-model="propModel" max-width="500px">
This works for me and do not need to create a puted data.
<v-dialog
width="600px"
:value="value"
@input="$emit('input', $event)"
>
</v-dialog>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744108958a4558859.html
评论列表(0条)