Обзор

Идея здесь состоит в том, чтобы показать, как создать стек навигации в вашем Ionic VueJS Application специально для модального диалога. Модальное диалоговое окно по-прежнему будет работать со страницами, помещая их в стек навигации, и изменения не повлияют на общую навигацию по приложению.

Исходный код доступен в конце сообщения в блоге, я отредактировал импорт, чтобы сделать код кратким.

Используется документация Ionic

IonNav — это автономный компонент для загрузки произвольных компонентов и добавления новых компонентов в стек.

Домашний компонент

Контейнер верхнего уровня для приложения. Основная цель этого компонента — открыть модальное окно, чтобы начать работу. Я очистил пустой шаблон, сгенерированный из @ionic-cli, чтобы начать проект.

Код для рендеринга и управления скрытием и отображением модального окна взят непосредственно из документации Ionic, указанной выше. Мы создаем реактивную переменную isOpenRef в компоненте, который определяет, видимо ли модальное окно или нет.

Home.vue

<ion-content :fullscreen="true" class="ion-padding">
  <ion-button @click="setOpen(true)">Show Modal With Nav</ion-button>
  <ion-modal
    :is-open="isOpenRef"
    @onDidDismiss="setOpen(false)"
  >
    <base-modal :rootPage="ModalHome"></base-modal>
  </ion-modal>
</ion-content>

Ниже приведен код javascript для открытия модального окна, а также обратите внимание, что мы импортируем компонент rootPage, ModalHome, который будет использоваться в шаблоне.

Вам нужно будет импортировать компонент, но его не нужно добавлять в раздел компонентов файла, но вам нужно вернуть его из функции setup, чтобы template мог получить доступ к значению.

import { ... } from "@ionic/vue";
import { defineComponent, ref } from "vue";
import BaseModal from "./BaseModal.vue";
// root page component defined here
import ModalHome from "./ModalHome.vue";

export default defineComponent({
  name: "Home",
  setup() {
    const isOpenRef = ref(false);
    const setOpen = (state: boolean) => (isOpenRef.value = state);
    return { isOpenRef, setOpen,  ModalHome };
  },
  components: { ... }
});

Компонент BaseModal

Контейнер для стека модальной навигации в приложении

BaseModal — это контейнер для всей навигации, которую мы собираемся делать в модальном окне. BaseModal визуализируется в компоненте Home.

rootPage назначается при отображении модального окна, а ion-nav используется для отображения страниц и навигации, когда мы перемещаемся по разным документам внутри модального окна.

обратите внимание, что я установил идентификатор modal-nav, чтобы я мог запрашивать документ, чтобы компонент выполнял соответствующие вызовы API.

BaseModal.vue

<template>
  <div>
    <ion-nav :root="rootPage" id="modal-nav"></ion-nav>
  </div>
</template>
<script>
import { defineComponent } from "vue";
import { IonNav } from "@ionic/vue";
export default defineComponent({
  name: "BaseModal",
  components: {
    IonNav
  },
  props: ["rootPage"],
});
</script>

Компонент ModalHome

rootPage в стеке модальной навигации

ModalHome.vue

<ion-page>
  <ion-header :translucent="true">
    <ion-toolbar>
      <ion-buttons slot="end">
        <ion-button @click="closeModal">CLOSE</ion-button>
      </ion-buttons>
      <ion-title>MODAL HOME</ion-title>
    </ion-toolbar>
  </ion-header>
  <ion-content class="ion-padding">
    <h2>MODAL HOME</h2>
    <ion-button @click="nextPage">SHOW MODAL DETAIL</ion-button>
  </ion-content>
</ion-page>

Вызовите document.getElementById, чтобы получить ion-nav, когда компонент смонтирован. Нам нужно импортировать следующую страницу, которую мы хотим отправить ModalHomeDetailVue
Передать свойства следующему компоненту как объекту при вызове метода push для ion-nav.

Я исследовал использование provide/inject, чтобы получить ModalNav и сохранить его с помощью provide, чтобы любой компонент в стеке модальной навигации мог получить к нему доступ; но я хотел, чтобы этот пример был как можно более простым и сосредоточился на ion-nav

Импортируйте modalController из @ionic/vue, чтобы мы могли полностью закрыть модальное окно и вернуться к стеку навигации приложения по умолчанию.

import { defineComponent, ref, onMounted } from "vue";
import { ... } from "@ionic/vue";
// the detail page
import ModalHomeDetailVue from "./ModalHomeDetail.vue";
export default defineComponent({
  name: "ModalHome",
  components: { ... },
  setup() {
    // the nav ref
    const modalNav = ref(null);
    // get the the ion-nav element so we can make
    // api calls using ion-nav
    onMounted(() => {
      const v = document.getElementById("modal-nav");
      modalNav.value = v;
    });
    /**
     *  when going to the next page, I pass the nav as a property
     * so I don't need to get it from the document again
     */
    const nextPage = () => {
      modalNav.value.push(ModalHomeDetailVue, {
        // these come across as properties on the component
        modalNav: modalNav
      });
    };
    /**
     * close the modal dialog
     */
    const closeModal = async () => {
      await modalController.dismiss();
    };
    return {
      nextPage,
      closeModal
    };
  }
});

Компонент ModalHomeDetail

Первая страница, помещенная в стек модальной навигации. В этом компоненте мы демонстрируем, как мы обрабатываем обратную навигацию и передаем свойства страницам/компонентам, когда мы помещаем их в стек, используя ion-nav.

ModalHomeDetail.vue

<ion-page>
  <ion-header :translucent="true">
    <ion-toolbar>
      <ion-buttons slot="start">
        <ion-button @click="goBack">BACK</ion-button>
      </ion-buttons>
      <ion-title>MODAL HOME DETAIL</ion-title>
    </ion-toolbar>
  </ion-header>
  <ion-content class="ion-padding">
    <h2>MODAL HOME DETAIL</h2>
  </ion-content>
</ion-page>

Из того, что я могу определить, мы должны сами обрабатывать заднюю часть, поэтому я добавил в компонент функцию для обработки этого, вызвав nav.pop(). Мы получаем ion-nav, потому что оно было передано как свойство компонента.

import { defineComponent } from "vue";
import { ... } from "@ionic/vue";
export default defineComponent({
  name: "ModalHomeDetail",
  components: { ... },
  props: [ "modalNav"],
  setup(props) {
    /**
     * get the nav from the props and go back
     */
    const goBack = () => {
      const nav = props.modalNav.value;
      nav.pop();
    };
    return {
      goBack
    };
  }
});

Тест на устройстве

У меня есть Mac, так что на нем основана большая часть моей работы; если у вас возникнут проблемы с Android, оставьте комментарий или опубликуйте проблему в репозитории github, и я свяжусь с вами.

ionic build
ionic cap add android
ionic cap add ios
ionic cap run ios --livereload

Исходный код

Полный исходный код проекта доступен в моем репозитории github вместе с набором другого
контента Ionic VueJS и ReactJS. Пожалуйста, посмотрите и оставьте комментарий. Также многие проекты связаны с YouTube контентом, который я создал на своем канале.



Посмотреть на GitHub

💥 Дополнительный контент

💥 Социальные сети