Joewy Lombe
Joewy Lombe

Reputation: 197

Custom Dialog Component Vuetify

Im trying to create a custom dialog component based on the v-dialog from vuetify framework.

<template>
    <v-dialog
      v-model="localDialog"
      max-width="290"
    >
      <v-card
      :color="localColor"
      >
        <v-card-title style="color:white;;" ><v-icon class="pr-2" color="white">{{localIcon}}</v-icon> {{localTitle}}</v-card-title>
        <v-card-text style="color:white; padding-top:5px;">
          {{message}}
        </v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn
            color="white"
            text
            @click="localDialog = false"
          >
            OK
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
</template>
<script>
export default {
    mounted(){
      this.initDialog();
    },
    props:[
      'type','message','dialog'
    ],
    data () {
      return {
        localDialog:this.dialog,
        localTitle:'Response',
        localColor:'red',
        localIcon:'mdi-alert-circle-outline'
      }
    },
    methods:{
      "initDialog": function () { console.log(this.dialog);
        switch (this.type) {
          case 'success':
            this.localIcon = "mdi-check-circle";
            this.localColor ="green";
            this.localTitle ="Operation Successful";
            break;
          case 'info':
            this.localIcon = "mdi-check-circle";
            this.localColor ="orange";
            this.localTitle ="Information";
             break;
          case 'error':
            this.localIcon = "mdi-alert-outline";
            this.localColor ="red";
            this.localTitle ="Error Occurred";
             break;
          default:
            this.localIcon = "mdi-alert-circle-outline";
            this.localColor ="blue";
            this.localTitle ="Information";
             break;
        }
      },
    } 
}
</script>

I understand how props work but i am having some difficulties toggling its status in the parent. Ideally what im trying to achieve is after an api call, i would like to display the dialog, not your normal "onClick" usage. But nothing happens after the api call.

In the parent

<dialog-message-component 
              :type=resultDialogType
              :message=resultDialogMessage
              :dialog=resultDialog
            />
    </v-dialog>

API Call

      Vue.axios.post("http://localhost:8080/api/events/store",
        {
          title: this.title,

        }
        ).then((response) => {
            var parsedobj = JSON.parse(JSON.stringify(response.data));
            console.log(parsedobj);
            this.overlay=false;
            this.resultDialogMessage=parsedobj.message;
            this.resultDialogType="info";
            this.resultDialog=true;
            }) ;

What am i doing wrong.

Upvotes: 1

Views: 1705

Answers (1)

Igor Moraru
Igor Moraru

Reputation: 7729

I think the problem is that data uses the value of passed properties as its INITIAL value. Any changes made to props afterwards are not passed to data, so it follow the concept of data() as local component memory, which can be manipulated locally, and props as external properties, which technically does not belong to the component, and shouldn't be mutated in the child component.

The simplest solution, is to create a watcher for the prop, and change local data on prop change.

watch: {
   dialog(val){
     this.localDialog = val
   }
}

Edited:

For passing the changed prop to the parent you use events:

Child:

<v-dialog @input="$emit('update:dialog', localDialog)">
...
</v-dialog>

Parent:

<dialog-message-component 
    :type=resultDialogType
    :message=resultDialogMessage
    :dialog.sync="resultDialog" // The equivalent of :dialog="resultDialog" @update:dialog='resultDialog = $event'
/>

Upvotes: 2

Related Questions