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; ionRoute: boolean;
mount: boolean; mount: boolean;
exact: boolean; exact: boolean;
registerCallback?: () => void;
} }
export interface ViewStacks { export interface ViewStacks {

View File

@ -3,7 +3,11 @@ import { h, defineComponent } from 'vue';
export const IonPage = defineComponent({ export const IonPage = defineComponent({
name: 'IonPage', name: 'IonPage',
props: { 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 }) { setup(props, { attrs, slots }) {
const hidePageClass = (props.isInOutlet) ? 'ion-page-invisible' : ''; const hidePageClass = (props.isInOutlet) ? 'ion-page-invisible' : '';

View File

@ -292,11 +292,10 @@ export const IonRouterOutlet = defineComponent({
if (!enteringViewItem.mount) { if (!enteringViewItem.mount) {
enteringViewItem.mount = true; enteringViewItem.mount = true;
enteringViewItem.vueComponent.components.IonPage.mounted = function () { enteringViewItem.registerCallback = () => {
viewStacks.registerIonPage(enteringViewItem, this.$refs.ionPage);
handlePageTransition(); handlePageTransition();
enteringViewItem.vueComponent.components.IonPage.mounted = undefined; enteringViewItem.registerCallback = undefined;
}; }
} else { } else {
handlePageTransition(); handlePageTransition();
} }
@ -315,20 +314,57 @@ export const IonRouterOutlet = defineComponent({
*/ */
onUnmounted(() => viewStacks.clear(id)); 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 { return {
id, id,
components, components,
ionRouterOutlet ionRouterOutlet,
registerIonPage
} }
}, },
render() { render() {
const { components } = this; const { components, registerIonPage } = this;
return h( return h(
'ion-router-outlet', 'ion-router-outlet',
{ ref: 'ionRouterOutlet' }, { ref: 'ionRouterOutlet' },
// TODO types // 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-content>
<ion-tabs id="tabs"> <ion-tabs id="tabs">
<ion-tab-bar slot="bottom"> <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-icon :icon="triangle" />
<ion-label>Tab 1</ion-label> <ion-label>Tab 1</ion-label>
</ion-tab-button> </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-icon :icon="ellipse" />
<ion-label>Tab 2</ion-label> <ion-label>Tab 2</ion-label>
</ion-tab-button> </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-icon :icon="square" />
<ion-label>Tab 3</ion-label> <ion-label>Tab 3</ion-label>
</ion-tab-button> </ion-tab-button>