I have created a child component which is a dialog box to which I am passing the prop dialog
from a parent component. I am not able to close it because changing the prop value gives a warning. What is the actual way to achieve this?
<template> <div> <v-dialog v-model="dialog" max-width="290" persistent> <v-card> <v-card-title class="headline"> {{ order.fullname }} </v-card-title> <v-card-text> {{ order.address }} </v-card-text> <v-card-actions> <v-spacer></v-spacer> <v-btn color="green darken-1" text @click="dialog = !dialog"> Disagree </v-btn> </v-card-actions> </v-card> </v-dialog> </div> </template> <script> export default { name: "EditOrder", props: ["order", "dialog"], data() { return { dialogCta: this.dialog, }; }, methods: { closeDialog() { // console.log(this.dialog); this.dialogCta = !this.dialog; console.log(this.dialogCta); }, }, }; </script>
Advertisement
Answer
Instead of modifying the prop
directly, you can create a computed
property that represents the value from the parent, and emits
an event on change
to close it from the last. Here is a demo:
const dialogmodel = Vue.component('btn', { template: '#dialogmodel', props: { order: Object, value: Boolean }, computed: { dialog: { get () { return this.value; }, set (value) { this.$emit('close', value); } } } }); new Vue({ el:"#app", vuetify: new Vuetify(), components: { dialogmodel }, data: () => ({ order: { fullname:"fullname", address:"address" }, dialog: true }), methods: { closeDialog(value) { this.dialog = value; } } });
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script><link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet"> <template id="dialogmodel"> <div> <v-dialog v-model="dialog" max-width="290" persistent> <v-card> <v-card-title class="headline"> {{ order.fullname }} </v-card-title> <v-card-text> {{ order.address }} </v-card-text> <v-card-actions> <v-spacer></v-spacer> <v-btn color="green darken-1" text @click="$emit('close')"> Disagree </v-btn> </v-card-actions> </v-card> </v-dialog> </div> </template> <v-app id="app"> <dialogmodel v-model="dialog" :order="order" @close="closeDialog" /> </v-app>