diff --git a/packages/vue-router/src/types.ts b/packages/vue-router/src/types.ts index efee6ad87c..839a70980d 100644 --- a/packages/vue-router/src/types.ts +++ b/packages/vue-router/src/types.ts @@ -39,6 +39,7 @@ export interface ViewItem { ionRoute: boolean; mount: boolean; exact: boolean; + registerCallback?: () => void; } export interface ViewStacks { diff --git a/packages/vue/src/components/IonPage.ts b/packages/vue/src/components/IonPage.ts index 1271619a8f..1e007e296c 100644 --- a/packages/vue/src/components/IonPage.ts +++ b/packages/vue/src/components/IonPage.ts @@ -3,7 +3,11 @@ import { h, defineComponent } from 'vue'; export const IonPage = defineComponent({ name: 'IonPage', props: { - isInOutlet: { type: Boolean, default: false } + isInOutlet: { type: Boolean, default: false }, + registerIonPage: { type: Function, default: () => {} } + }, + mounted() { + this.$props.registerIonPage(this.$refs.ionPage); }, setup(props, { attrs, slots }) { const hidePageClass = (props.isInOutlet) ? 'ion-page-invisible' : ''; diff --git a/packages/vue/src/components/IonRouterOutlet.ts b/packages/vue/src/components/IonRouterOutlet.ts index f32dc96a52..841fee129c 100644 --- a/packages/vue/src/components/IonRouterOutlet.ts +++ b/packages/vue/src/components/IonRouterOutlet.ts @@ -292,11 +292,10 @@ export const IonRouterOutlet = defineComponent({ if (!enteringViewItem.mount) { enteringViewItem.mount = true; - enteringViewItem.vueComponent.components.IonPage.mounted = function () { - viewStacks.registerIonPage(enteringViewItem, this.$refs.ionPage); + enteringViewItem.registerCallback = () => { handlePageTransition(); - enteringViewItem.vueComponent.components.IonPage.mounted = undefined; - }; + enteringViewItem.registerCallback = undefined; + } } else { handlePageTransition(); } @@ -315,20 +314,57 @@ export const IonRouterOutlet = defineComponent({ */ onUnmounted(() => viewStacks.clear(id)); + // TODO types + const registerIonPage = (viewItem: any, ionPageEl: HTMLElement) => { + const oldIonPageEl = viewItem.ionPageElement; + + viewStacks.registerIonPage(viewItem, ionPageEl); + + /** + * If there is a registerCallback, + * then this component is being registered + * as a result of a navigation change. + */ + if (viewItem.registerCallback) { + viewItem.registerCallback(); + + /** + * If there is no registerCallback, then + * this component is likely being re-registered + * as a result of a hot module replacement. + * We need to see if the oldIonPageEl has + * .ion-page-invisible. If it does not then we + * need to remove it from the new ionPageEl otherwise + * the page will be hidden when it is replaced. + */ + } else if (oldIonPageEl && !oldIonPageEl.classList.contains('ion-page-invisible')) { + ionPageEl.classList.remove('ion-page-invisible'); + } + }; return { id, components, - ionRouterOutlet + ionRouterOutlet, + registerIonPage } }, render() { - const { components } = this; + const { components, registerIonPage } = this; return h( 'ion-router-outlet', { ref: 'ionRouterOutlet' }, // TODO types - components && components.map((c: any) => h(c.vueComponent, { key: c.pathname, isInOutlet: true })) + components && components.map((c: any) => { + return h( + c.vueComponent, + { + key: c.pathname, + isInOutlet: true, + registerIonPage: (ionPageEl: HTMLElement) => registerIonPage(c, ionPageEl) + } + ) + }) ) } }); diff --git a/packages/vue/test-app/src/views/TabsSecondary.vue b/packages/vue/test-app/src/views/TabsSecondary.vue index fcc2d81253..491fbd8e38 100644 --- a/packages/vue/test-app/src/views/TabsSecondary.vue +++ b/packages/vue/test-app/src/views/TabsSecondary.vue @@ -3,17 +3,17 @@ - + Tab 1 - + Tab 2 - + Tab 3