diff --git a/packages/vue-router/src/viewStacks.ts b/packages/vue-router/src/viewStacks.ts
index 1ef105125d..7fd5c331da 100644
--- a/packages/vue-router/src/viewStacks.ts
+++ b/packages/vue-router/src/viewStacks.ts
@@ -20,6 +20,14 @@ export const createViewStacks = (router: Router) => {
const registerIonPage = (viewItem: ViewItem, ionPage: HTMLElement) => {
viewItem.ionPageElement = ionPage;
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) => {
@@ -202,6 +210,7 @@ export const createViewStacks = (router: Router) => {
viewItem.mount = false;
viewItem.ionPageElement = undefined;
viewItem.ionRoute = false;
+ viewItem.matchedRoute.instances = {};
}
}
diff --git a/packages/vue/src/components/IonRouterOutlet.ts b/packages/vue/src/components/IonRouterOutlet.ts
index 4eea4a8915..ffbad4d255 100644
--- a/packages/vue/src/components/IonRouterOutlet.ts
+++ b/packages/vue/src/components/IonRouterOutlet.ts
@@ -63,7 +63,7 @@ export const IonRouterOutlet = defineComponent({
* page/1 to page/2 would not cause this callback
* 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,
* then we need to set up a new view item.
diff --git a/packages/vue/test-app/tests/unit/routing.spec.ts b/packages/vue/test-app/tests/unit/routing.spec.ts
index 0a14f980aa..ae510fc22e 100644
--- a/packages/vue/test-app/tests/unit/routing.spec.ts
+++ b/packages/vue/test-app/tests/unit/routing.spec.ts
@@ -393,4 +393,52 @@ describe('Routing', () => {
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: ``
+ }
+ const Page2 = {
+ components: { IonPage },
+ template: ``
+ }
+
+ 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);
+ });
});