fix(vue): ion-page component is properly shown with HMR (#22319)

This commit is contained in:
Liam DeBeasi
2020-10-14 18:45:46 -04:00
committed by GitHub
parent 6e9e58ed61
commit c5ab562eaa
4 changed files with 52 additions and 11 deletions

View File

@@ -39,6 +39,7 @@ export interface ViewItem {
ionRoute: boolean;
mount: boolean;
exact: boolean;
registerCallback?: () => void;
}
export interface ViewStacks {

View File

@@ -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' : '';

View File

@@ -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)
}
)
})
)
}
});

View File

@@ -3,17 +3,17 @@
<ion-content>
<ion-tabs id="tabs">
<ion-tab-bar slot="bottom">
<ion-tab-button tab="tab1" href="/tabs-secondary/tab1">
<ion-tab-button tab="tab1-secondary" href="/tabs-secondary/tab1">
<ion-icon :icon="triangle" />
<ion-label>Tab 1</ion-label>
</ion-tab-button>
<ion-tab-button tab="tab2" href="/tabs-secondary/tab2">
<ion-tab-button tab="tab2-secondary" href="/tabs-secondary/tab2">
<ion-icon :icon="ellipse" />
<ion-label>Tab 2</ion-label>
</ion-tab-button>
<ion-tab-button tab="tab3" href="/tabs-secondary/tab3">
<ion-tab-button tab="tab3-secondary" href="/tabs-secondary/tab3">
<ion-icon :icon="square" />
<ion-label>Tab 3</ion-label>
</ion-tab-button>