From fb96ab5a26d87818a8b64ee82df0020355054183 Mon Sep 17 00:00:00 2001 From: Yuhongjie Date: Wed, 24 Nov 2021 06:04:24 +0800 Subject: [PATCH] fix(vue): ionic lifecycle hooks now run when using vue 3.2 setup syntax (#24253) resolves #23824 Co-authored-by: Liam DeBeasi --- packages/vue/src/hooks.ts | 6 ++ packages/vue/test-app/src/router/index.ts | 4 ++ packages/vue/test-app/src/views/Home.vue | 3 + .../vue/test-app/src/views/LifecycleSetup.vue | 56 ++++++++++++++++++ .../vue/test-app/tests/e2e/specs/lifecycle.js | 58 +++++++++++++++++-- 5 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 packages/vue/test-app/src/views/LifecycleSetup.vue diff --git a/packages/vue/src/hooks.ts b/packages/vue/src/hooks.ts index 68d3e023c6..e04919e10a 100644 --- a/packages/vue/src/hooks.ts +++ b/packages/vue/src/hooks.ts @@ -80,6 +80,12 @@ const injectHook = (lifecycleType: LifecycleHooks, hook: Function, component: Co // Add to public instance so it is accessible to IonRouterOutlet const target = component as any; const hooks = target.proxy[lifecycleType] || (target.proxy[lifecycleType] = []); + /** + * Define property on public instances using `setup` syntax in Vue 3.x + */ + if (target.exposed) { + target.exposed[lifecycleType] = hooks; + } const wrappedHook = (...args: unknown[]) => { if (target.isUnmounted) { return; diff --git a/packages/vue/test-app/src/router/index.ts b/packages/vue/test-app/src/router/index.ts index 98818af6d4..7213a3bac8 100644 --- a/packages/vue/test-app/src/router/index.ts +++ b/packages/vue/test-app/src/router/index.ts @@ -17,6 +17,10 @@ const routes: Array = [ path: '/lifecycle', component: () => import('@/views/Lifecycle.vue') }, + { + path: '/lifecycle-setup', + component: () => import('@/views/LifecycleSetup.vue') + }, { path: '/overlays', name: 'Overlays', diff --git a/packages/vue/test-app/src/views/Home.vue b/packages/vue/test-app/src/views/Home.vue index e09d0a3b96..14f307ce3e 100644 --- a/packages/vue/test-app/src/views/Home.vue +++ b/packages/vue/test-app/src/views/Home.vue @@ -47,6 +47,9 @@ Lifecycle + + Lifecycle (Setup) + Delayed Redirect diff --git a/packages/vue/test-app/src/views/LifecycleSetup.vue b/packages/vue/test-app/src/views/LifecycleSetup.vue new file mode 100644 index 0000000000..b31b162040 --- /dev/null +++ b/packages/vue/test-app/src/views/LifecycleSetup.vue @@ -0,0 +1,56 @@ + + + diff --git a/packages/vue/test-app/tests/e2e/specs/lifecycle.js b/packages/vue/test-app/tests/e2e/specs/lifecycle.js index 478e3f119b..d9d22064ea 100644 --- a/packages/vue/test-app/tests/e2e/specs/lifecycle.js +++ b/packages/vue/test-app/tests/e2e/specs/lifecycle.js @@ -55,14 +55,62 @@ describe('Lifecycle', () => { onIonViewDidLeave: 0 }); }); + + it('should fire lifecycle events when navigating to and from a page - setup', () => { + cy.visit('http://localhost:8080'); + cy.get('#lifecycle-setup').click(); + + testLifecycle('lifecycle-setup', { + onIonViewWillEnter: 1, + onIonViewDidEnter: 1, + onIonViewWillLeave: 0, + onIonViewDidLeave: 0 + }); + + cy.get('#lifecycle-navigation').click(); + + testLifecycle('lifecycle-setup', { + onIonViewWillEnter: 1, + onIonViewDidEnter: 1, + onIonViewWillLeave: 1, + onIonViewDidLeave: 1 + }); + + cy.ionBackClick('navigation'); + + testLifecycle('lifecycle-setup', { + onIonViewWillEnter: 2, + onIonViewDidEnter: 2, + onIonViewWillLeave: 1, + onIonViewDidLeave: 1 + }); + }); + + it('should fire lifecycle events when landed on directly - setup', () => { + cy.visit('http://localhost:8080/lifecycle-setup'); + + testLifecycle('lifecycle-setup', { + onIonViewWillEnter: 1, + onIonViewDidEnter: 1, + onIonViewWillLeave: 0, + onIonViewDidLeave: 0 + }); + }); }) const testLifecycle = (selector, expected = {}) => { - cy.get(`[data-pageid=${selector}] #willEnter`).should('have.text', expected.ionViewWillEnter); - cy.get(`[data-pageid=${selector}] #didEnter`).should('have.text', expected.ionViewDidEnter); - cy.get(`[data-pageid=${selector}] #willLeave`).should('have.text', expected.ionViewWillLeave); - cy.get(`[data-pageid=${selector}] #didLeave`).should('have.text', expected.ionViewDidLeave); - + if (expected.ionViewWillEnter) { + cy.get(`[data-pageid=${selector}] #willEnter`).should('have.text', expected.ionViewWillEnter); + } + if (expected.ionViewDidEnter) { + cy.get(`[data-pageid=${selector}] #didEnter`).should('have.text', expected.ionViewDidEnter); + } + if (expected.ionViewWillLeave) { + cy.get(`[data-pageid=${selector}] #willLeave`).should('have.text', expected.ionViewWillLeave); + } + if (expected.ionViewDidLeave) { + cy.get(`[data-pageid=${selector}] #didLeave`).should('have.text', expected.ionViewDidLeave); + } cy.get(`[data-pageid=${selector}] #onWillEnter`).should('have.text', expected.onIonViewWillEnter); cy.get(`[data-pageid=${selector}] #onDidEnter`).should('have.text', expected.onIonViewDidEnter); cy.get(`[data-pageid=${selector}] #onWillLeave`).should('have.text', expected.onIonViewWillLeave);