Can't close the modal in Ionic-vue 5.5.2

Viewed 1981

in this version of @ionic/vue@0.5.5.2 I can't use a component and assign a reference (< Login ref="modal"/>) to it to close it in the Modal component (Login.vue), so I don't know how to close it from Login.vue. I leave my code:

Home.vue

<template>
<ion-page>
    <ion-header>
        <ion-toolbar>
            <ion-title>
                Title
            </ion-title>
        </ion-toolbar>
    </ion-header>

    <ion-content class="auth-form">

        <ion-grid>
            <ion-row>
                <ion-col align-self-center>
                    <ion-button @click="openModal" expand="block" color="primary">Registrarme</ion-button>

                    <span class="divider line one-line">o</span>

                    <span class="already">¿Tienes una cuenta?</span>

                    <ion-button @click="openModal" expand="block" color="danger">Iniciar sesión</ion-button>
                </ion-col>
            </ion-row>
        </ion-grid>
       
    </ion-content>

</ion-page>
</template>

<script>
import {
    IonContent,
    modalController,
    IonTitle,
    IonToolbar,
    IonHeader,
    IonButton,
    IonCol,
    IonRow,
    IonGrid,
    IonPage
} from '@ionic/vue';
import Login from '../views/Login.vue';

export default {
    name: 'inicio',
    components: {
       
        IonContent,
        IonTitle,
        IonToolbar,
        IonHeader,
        IonButton,
        IonCol,
        IonRow,
        IonGrid,
        IonPage
    },
    data() {
        return {
            modal: '',
            isOpen: false,
        }
    },

    methods: {
        async createModal() {
            this.modal = await modalController.create({
                component: Login,
                componentProps: {
                  title: 'Iniciar sesión'
              },
                
            })
        },
        async openModal() {
            await this.createModal()
            this.isOpen = true
            this.modal.present()
        },
        closeModal() {
            this.isOpen = false
            this.modal.dismiss().then(() => {
                this.modal = null;
            });
        },
    },
}
</script>

And my Login.vue:

<template>
<ion-page>
    <ion-header translucent>
        <ion-toolbar>
            <ion-title>{{ title }}</ion-title>
            <ion-buttons slot="end">
                <ion-button @click="cerrarmodal">Cerrar</ion-button>
            </ion-buttons>
        </ion-toolbar>
    </ion-header>

    <ion-content>

        <ion-list>

            <ion-item>
                <ion-label>Email</ion-label>
                <ion-input type="text"></ion-input>
            </ion-item>

            <ion-item>
                <ion-label>Contraseña</ion-label>
                <ion-input type="password"></ion-input>
            </ion-item>

        </ion-list>

        <ion-button color="primary" expand="block">Ingresar</ion-button>

    </ion-content>

</ion-page>
</template>

<script>
import {
    IonButtons,
    IonContent,
    IonButton,
    IonToolbar,
    IonHeader,
    IonTitle,
    IonList,
    IonLabel,
    IonInput,
    IonItem,
    IonPage
} from '@ionic/vue';
import {
    defineComponent
} from 'vue';

export default defineComponent({
    name: 'login',
    props: {
        title: {
            type: String,
            default: 'Super Modal'
        },
        closeMe: {
            type: Function,
            default: () => {
                ''
            }
        },
    },
    data() {
        return {
            content: 'Content',
        }
    },
    methods: {
        cerrarmodal() {
            this.$emit('close', {
                foo: 'bar'
            })
            // Not working
            this.$parent.closeModal()
        },
   
    },
    components: {
        IonButton,
        IonButtons,
        IonToolbar,
        IonList,
        IonInput,
        IonLabel,
        IonItem,
        IonPage,
        IonHeader,
        IonTitle,
        IonContent
    },
});
</script>

I've tried $ emit and $ parent.closeModal () but no luck, thanks for your help in advance.

4 Answers

I confirm that the best and simple way to solve this is calling dismiss() function of modalController.

First we must import modalController in our modal component:

import { modalController } from "@ionic/vue";

Next we can close modal like this:

async function close() {
  await modalController.dismiss();
}

Important: I use await because dismiss return a promise so it's important use it.

I resolved it by passing a prop "close" with the function closeModal and defining the prop "close" in the modal component and then calling it with a this.close

this.modal = await modalController.create({
                component: Login,
                componentProps: {
                  title: 'Iniciar sesión',
                  close: () => this.closeModal()
              },
                
            })

In modal component:

props: {
        title: {
            type: String,
            default: 'Super Modal'
        },
        close: { type: Function }
    },

cerrarmodal() {
            this.$emit('close', {
                foo: 'bar'
            })
            this.close()
            
        },

I think you can call

modalController.dismiss()

to close any open dialog... also the emit should have worked, didn't see that code

<!-- ./modal.vue -->

<template>
  <ion-header>
    <ion-toolbar>
      <ion-button shape="round" fill="clear" @click="modalController.dismiss()">
          <ion-icon slot="icon-only" :icon="arrowBackOutline" />
        </ion-button>
    </ion-toolbar>
  </ion-header>
  <ion-content class="ion-padding">
    {{ content }}
  </ion-content>
</template>

<script lang="ts">
import { IonButton, IonHeader,  IonToolbar, IonContent } from '@ionic/vue';
import { arrowBackOutline } from 'ionicons/icons';
import { modalController } from "@ionic/vue";

export default {
  name: 'Modal',
  components: { IonButton, IonHeader, IonToolbar, IonContent },
  setup(){
    const content = 'Content';
    return {
      content,
      modalController,
      arrowBackOutline,
      IonHeader,
      IonToolbar
    }
  }
}
</script>
Related