mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 17:42:15 +08:00
fix(vue): improve compatibility with route guards (#22371)
resolves #22344
This commit is contained in:
@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
Router,
|
Router,
|
||||||
RouteLocationNormalized,
|
RouteLocationNormalized
|
||||||
NavigationGuardNext
|
|
||||||
} from 'vue-router';
|
} from 'vue-router';
|
||||||
import { createLocationHistory } from './locationHistory';
|
import { createLocationHistory } from './locationHistory';
|
||||||
import { generateId } from './utils';
|
import { generateId } from './utils';
|
||||||
@ -19,13 +18,20 @@ import { AnimationBuilder } from '@ionic/core';
|
|||||||
export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) => {
|
export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) => {
|
||||||
let currentNavigationInfo: NavigationInformation = { direction: undefined, action: undefined };
|
let currentNavigationInfo: NavigationInformation = { direction: undefined, action: undefined };
|
||||||
|
|
||||||
router.beforeEach((to: RouteLocationNormalized, _: RouteLocationNormalized, next: NavigationGuardNext) => {
|
/**
|
||||||
|
* Ionic Vue should only react to navigation
|
||||||
|
* changes once they have been confirmed and should
|
||||||
|
* never affect the outcome of navigation (with the
|
||||||
|
* exception of going back or selecting a tab).
|
||||||
|
* As a result, we should do our work in afterEach
|
||||||
|
* which is fired once navigation is confirmed
|
||||||
|
* and any user guards have run.
|
||||||
|
*/
|
||||||
|
router.afterEach((to: RouteLocationNormalized, _: RouteLocationNormalized) => {
|
||||||
const { direction, action } = currentNavigationInfo;
|
const { direction, action } = currentNavigationInfo;
|
||||||
handleHistoryChange(to, action, direction);
|
handleHistoryChange(to, action, direction);
|
||||||
|
|
||||||
currentNavigationInfo = { direction: undefined, action: undefined };
|
currentNavigationInfo = { direction: undefined, action: undefined };
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const locationHistory = createLocationHistory();
|
const locationHistory = createLocationHistory();
|
||||||
|
18
packages/vue/test-app/src/guards/Delay.ts
Normal file
18
packages/vue/test-app/src/guards/Delay.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { loadingController } from '@ionic/vue';
|
||||||
|
import {
|
||||||
|
NavigationGuardNext,
|
||||||
|
RouteLocationNormalized
|
||||||
|
} from 'vue-router';
|
||||||
|
|
||||||
|
export const DelayGuard = async (_: RouteLocationNormalized, _x: RouteLocationNormalized, next: NavigationGuardNext) => {
|
||||||
|
const loading = await loadingController.create({
|
||||||
|
message: 'Waiting 500ms...',
|
||||||
|
duration: 500
|
||||||
|
});
|
||||||
|
|
||||||
|
await loading.present();
|
||||||
|
|
||||||
|
await loading.onDidDismiss();
|
||||||
|
|
||||||
|
next({ path: '/routing' });
|
||||||
|
}
|
@ -1,12 +1,18 @@
|
|||||||
import { createRouter, createWebHistory } from '@ionic/vue-router';
|
import { createRouter, createWebHistory } from '@ionic/vue-router';
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
import Home from '../views/Home.vue'
|
import Home from '@/views/Home.vue'
|
||||||
|
import { DelayGuard } from '@/guards/Delay';
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: Array<RouteRecordRaw> = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
component: Home
|
component: Home
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/delayed-redirect',
|
||||||
|
beforeEnter: DelayGuard,
|
||||||
|
component: Home
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/lifecycle',
|
path: '/lifecycle',
|
||||||
component: () => import('@/views/Lifecycle.vue')
|
component: () => import('@/views/Lifecycle.vue')
|
||||||
@ -89,6 +95,9 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'tab3',
|
path: 'tab3',
|
||||||
|
beforeEnter: (to, from, next) => {
|
||||||
|
next({ path: '/tabs/tab1' });
|
||||||
|
},
|
||||||
component: () => import('@/views/Tab3.vue')
|
component: () => import('@/views/Tab3.vue')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -120,6 +129,6 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(process.env.BASE_URL),
|
history: createWebHistory(process.env.BASE_URL),
|
||||||
routes
|
routes
|
||||||
})
|
});
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
@ -44,6 +44,9 @@
|
|||||||
<ion-item router-link="/lifecycle" id="lifecycle">
|
<ion-item router-link="/lifecycle" id="lifecycle">
|
||||||
<ion-label>Lifecycle</ion-label>
|
<ion-label>Lifecycle</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
<ion-item router-link="/delayed-redirect" id="delayed-redirect">
|
||||||
|
<ion-label>Delayed Redirect</ion-label>
|
||||||
|
</ion-item>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
@ -62,7 +62,23 @@ describe('Routing', () => {
|
|||||||
|
|
||||||
cy.ionPageDoesNotExist('routingparameter');
|
cy.ionPageDoesNotExist('routingparameter');
|
||||||
cy.ionPageVisible('routing');
|
cy.ionPageVisible('routing');
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/22359
|
||||||
|
it('should work properly with async navigation guards', () => {
|
||||||
|
cy.visit('http://localhost:8080');
|
||||||
|
cy.get('#delayed-redirect').click();
|
||||||
|
|
||||||
|
cy.get('ion-loading').should('exist');
|
||||||
|
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
|
cy.ionBackClick('routing');
|
||||||
|
|
||||||
|
cy.ionPageVisible('home');
|
||||||
|
cy.ionPageDoesNotExist('routing');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Routing - Swipe to Go Back', () => {
|
describe('Routing - Swipe to Go Back', () => {
|
||||||
|
@ -113,6 +113,15 @@ describe('Tabs', () => {
|
|||||||
cy.get('ion-tab-button#tab-button-tab2').click();
|
cy.get('ion-tab-button#tab-button-tab2').click();
|
||||||
cy.ionPageVisible('tab2');
|
cy.ionPageVisible('tab2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/22344
|
||||||
|
it('should show tab 1 when redirecting from tab 3', () => {
|
||||||
|
cy.visit('http://localhost:8080/tabs/tab3');
|
||||||
|
|
||||||
|
cy.ionPageVisible('tab1');
|
||||||
|
cy.ionPageDoesNotExist('tab3');
|
||||||
|
cy.ionPageVisible('tabs');
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Tabs - Swipe to Go Back', () => {
|
describe('Tabs - Swipe to Go Back', () => {
|
||||||
|
Reference in New Issue
Block a user