Reputation: 2754
I'm currently opening a dialog component using this
Parent
<v-btn color="#EF5350" dark small absolute top right fab
@click="showDialog">
<v-icon>zoom_in</v-icon>
</v-btn>
<UIDialog :dialog="dialog" @updateDialog="dialog = $event" />
<script>
import UIDialog from '@/components/UI/UIDialog';
export default {
data() {
return {
dialog: false
}
}
components: {
UIDialog
},
methods: {
showDialog() {
this.dialog = true;
}
}
}
</script>
This opens the dialog since I set dialog to true
Child
<v-dialog v-model="dialog" fullscreen scrollable>
<v-card>
This is a test
</v-card>
</v-dialog>
<script>
export default {
props: {
dialog: { type: Boolean, default: false }
},
watch: {
dialog(val) {
if (!val) this.$emit('updateDialog', false)
}
}
}
</script>
I use watch since vue dialog doesn't have event. I managed to close the dialog but I'm still getting
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
Upvotes: 6
Views: 3473
Reputation: 117
Use :value
and @input
instead of declaring prop to v-model
Prop mutation error happens because v-model
have already :value
and its mutator, which is triggers this error. If you will use simple :value
and declare for @input
method close()
it will work
Upvotes: 0
Reputation: 273
This worked for me:
Parent
<app-my-dialog :dialog="doShowDialog" @close="doShowDialog = false"></app-my-dialog>
Child component (app-my-dialog)
<template>
<v-dialog :value="showDialog" @click:outside="close()">
<v-btn @click="close()">Close</v-btn>
</v-dialog>
</template>
<script>
export default {
props: {
dialog: {
type: Boolean,
default: false
}
},
computed: {
showDialog() {
return this.dialog;
}
},
methods: {
close() {
this.$emit('close')
},
}
}
</script>
Note that if you use <v-dialog :persistent="true" ...
(that means the dialog won't close on click outside itself), you can omit the @click:outside="close()"
Upvotes: 1
Reputation: 286
Decompose your v-model on UIDialog, in favor of
<v-dialog v-bind:value="dialog" v-on:input="emitOutput">
where emitOutput
outputs a 'value' event
emitOutput(value) {
this.$emit('input', value)
}
-- This should handle the message of prop mutation in the console and also provide component level visibility control. You won't need to do any handling for custom events on the parent when emitting an 'input' event.
Upvotes: 0
Reputation: 2754
I managed to solve my problem by using computed property to get and set the dialog
Child
<v-dialog v-model="dialog" fullscreen scrollable>
<v-card>
This is a test
</v-card>
</v-dialog>
<script>
export default {
props: {
dialog: { type: Boolean, default: false }
},
computed: {
dialogState: {
get() {
return this.dialog;
},
set(val) {
this.$emit('updateDialog', false);
}
}
}
}
</script>
Upvotes: 2