fix(vue): router guards are now fired correctly when written in a component (#23821)

resolves #23820
This commit is contained in:
Liam DeBeasi
2021-08-26 10:40:48 -04:00
committed by GitHub
parent 50b88b24c2
commit 3c442228ff
3 changed files with 58 additions and 1 deletions

View File

@ -20,6 +20,14 @@ export const createViewStacks = (router: Router) => {
const registerIonPage = (viewItem: ViewItem, ionPage: HTMLElement) => { const registerIonPage = (viewItem: ViewItem, ionPage: HTMLElement) => {
viewItem.ionPageElement = ionPage; viewItem.ionPageElement = ionPage;
viewItem.ionRoute = true; viewItem.ionRoute = true;
/**
* This is needed otherwise Vue Router
* will not consider this component mounted
* and will not run route guards that
* are written in the component.
*/
viewItem.matchedRoute.instances = { default: viewItem.vueComponentRef.value };
} }
const findViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, useDeprecatedRouteSetup: boolean = false) => { const findViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, useDeprecatedRouteSetup: boolean = false) => {
@ -202,6 +210,7 @@ export const createViewStacks = (router: Router) => {
viewItem.mount = false; viewItem.mount = false;
viewItem.ionPageElement = undefined; viewItem.ionPageElement = undefined;
viewItem.ionRoute = false; viewItem.ionRoute = false;
viewItem.matchedRoute.instances = {};
} }
} }

View File

@ -63,7 +63,7 @@ export const IonRouterOutlet = defineComponent({
* page/1 to page/2 would not cause this callback * page/1 to page/2 would not cause this callback
* to fire since the matchedRouteRef was the same. * to fire since the matchedRouteRef was the same.
*/ */
watch([route, matchedRouteRef], ([currentRoute, currentMatchedRouteRef], [_, previousMatchedRouteRef]) => { watch(() => [route, matchedRouteRef.value], ([currentRoute, currentMatchedRouteRef], [_, previousMatchedRouteRef]) => {
/** /**
* If the matched route ref has changed, * If the matched route ref has changed,
* then we need to set up a new view item. * then we need to set up a new view item.

View File

@ -393,4 +393,52 @@ describe('Routing', () => {
expect(page.props()).toEqual({ id: '2' }); expect(page.props()).toEqual({ id: '2' });
}); });
it('should fire guard written in a component', async () => {
const beforeRouteEnterSpy = jest.fn();
const beforeRouteLeaveSpy = jest.fn();
const Page = {
beforeRouteEnter() {
beforeRouteEnterSpy();
},
beforeRouteLeave() {
beforeRouteLeaveSpy();
},
components: { IonPage },
template: `<ion-page></ion-page>`
}
const Page2 = {
components: { IonPage },
template: `<ion-page></ion-page>`
}
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes: [
{ path: '/page', component: Page },
{ path: '/page2', component: Page2 },
{ path: '/', redirect: '/page' }
]
});
router.push('/');
await router.isReady();
const wrapper = mount(App, {
global: {
plugins: [router, IonicVue]
}
});
expect(beforeRouteEnterSpy).toHaveBeenCalledTimes(1);
router.push('/page2');
await waitForRouter();
expect(beforeRouteLeaveSpy).toHaveBeenCalledTimes(1);
router.back();
await waitForRouter();
expect(beforeRouteEnterSpy).toHaveBeenCalledTimes(2);
});
}); });