mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
fix(vue): navigating between parameterized pages now results in page transition (#23525)
resolves #22662
This commit is contained in:
@ -23,31 +23,7 @@ export const createViewStacks = (router: Router) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const findViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number) => {
|
const findViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number) => {
|
||||||
let viewItem = findViewItemByPath(routeInfo.pathname, outletId, false);
|
return findViewItemByPath(routeInfo.pathname, outletId, false);
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a route such as /path/:id,
|
|
||||||
* going from /page/1 to /home
|
|
||||||
* to /page/2 will cause the same
|
|
||||||
* view item from /page/1 to match
|
|
||||||
* for /page/2 so we need to make
|
|
||||||
* sure any params get updated.
|
|
||||||
* Not normally an issue for accessing
|
|
||||||
* the params via useRouter from vue-router,
|
|
||||||
* but when passing params as props not doing
|
|
||||||
* this would cause the old props to show up.
|
|
||||||
*/
|
|
||||||
if (viewItem && viewItem.params !== routeInfo.params) {
|
|
||||||
/**
|
|
||||||
* Clear the props function result
|
|
||||||
* as the value may have changed due
|
|
||||||
* to different props.
|
|
||||||
*/
|
|
||||||
delete viewItem.vueComponentData.propsFunctionResult;
|
|
||||||
viewItem.params = routeInfo.params;
|
|
||||||
}
|
|
||||||
|
|
||||||
return viewItem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const findLeavingViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, mustBeIonRoute: boolean = true) => {
|
const findLeavingViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, mustBeIonRoute: boolean = true) => {
|
||||||
@ -81,6 +57,20 @@ export const createViewStacks = (router: Router) => {
|
|||||||
const findMatchedRoute = resolvedPath.matched.find((matchedRoute: RouteLocationMatched) => matchedRoute === viewItem.matchedRoute);
|
const findMatchedRoute = resolvedPath.matched.find((matchedRoute: RouteLocationMatched) => matchedRoute === viewItem.matchedRoute);
|
||||||
|
|
||||||
if (findMatchedRoute) {
|
if (findMatchedRoute) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* /page/1 and /page/2 should not match
|
||||||
|
* to the same view item otherwise there will
|
||||||
|
* be not page transition and we will need to
|
||||||
|
* explicitly clear out parameters from page 1
|
||||||
|
* so the page 2 params are properly passed
|
||||||
|
* to the developer's app.
|
||||||
|
*/
|
||||||
|
const hasParameter = findMatchedRoute.path.includes(':');
|
||||||
|
if (hasParameter && path !== viewItem.pathname) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return viewItem;
|
return viewItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,12 +90,9 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
component: () => import('@/views/Tab1.vue'),
|
component: () => import('@/views/Tab1.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'tab1/child-one',
|
path: 'tab1/:id',
|
||||||
component: () => import('@/views/Tab1ChildOne.vue')
|
component: () => import('@/views/Tab1Parameter.vue'),
|
||||||
},
|
props: true
|
||||||
{
|
|
||||||
path: 'tab1/child-two',
|
|
||||||
component: () => import('@/views/Tab1ChildTwo.vue')
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'tab2',
|
path: 'tab2',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<ion-page data-pageid="routingparameter">
|
<ion-page :data-pageid="'routingparameter-' + $props.id">
|
||||||
<ion-header :translucent="true">
|
<ion-header :translucent="true">
|
||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-buttons>
|
<ion-buttons>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<ExploreContainer name="Tab 1 page" />
|
<ExploreContainer name="Tab 1 page" />
|
||||||
|
|
||||||
<ion-item button router-link="/tabs/tab1/child-one" id="child-one">
|
<ion-item button router-link="/tabs/tab1/childone" id="child-one">
|
||||||
<ion-label>Go to Tab 1 Child 1</ion-label>
|
<ion-label>Go to Tab 1 Child 1</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item button router-link="/nested" id="nested">
|
<ion-item button router-link="/nested" id="nested">
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
<template>
|
|
||||||
<ion-page data-pageid="tab1childtwo">
|
|
||||||
<ion-header>
|
|
||||||
<ion-toolbar>
|
|
||||||
<ion-buttons>
|
|
||||||
<ion-back-button></ion-back-button>
|
|
||||||
</ion-buttons>
|
|
||||||
<ion-title>Tab 1 Child 2</ion-title>
|
|
||||||
</ion-toolbar>
|
|
||||||
</ion-header>
|
|
||||||
<ion-content :fullscreen="true">
|
|
||||||
<ion-header collapse="condense">
|
|
||||||
<ion-toolbar>
|
|
||||||
<ion-title size="large">Tab 1 Child 2</ion-title>
|
|
||||||
</ion-toolbar>
|
|
||||||
</ion-header>
|
|
||||||
|
|
||||||
</ion-content>
|
|
||||||
</ion-page>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
IonButtons,
|
|
||||||
IonBackButton,
|
|
||||||
IonPage,
|
|
||||||
IonHeader,
|
|
||||||
IonToolbar,
|
|
||||||
IonTitle,
|
|
||||||
IonContent
|
|
||||||
} from '@ionic/vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
IonButtons,
|
|
||||||
IonBackButton,
|
|
||||||
IonPage,
|
|
||||||
IonHeader,
|
|
||||||
IonToolbar,
|
|
||||||
IonTitle,
|
|
||||||
IonContent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,21 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<ion-page data-pageid="tab1childone">
|
<ion-page :data-pageid="'tab1' + $props.id">
|
||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-buttons>
|
<ion-buttons>
|
||||||
<ion-back-button></ion-back-button>
|
<ion-back-button></ion-back-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<ion-title>Tab 1 Child 1</ion-title>
|
<ion-title>Tab 1 Child {{ $props.id }}</ion-title>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content :fullscreen="true">
|
<ion-content :fullscreen="true">
|
||||||
<ion-header collapse="condense">
|
<ion-header collapse="condense">
|
||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-title size="large">Tab 1 Child 1</ion-title>
|
<ion-title size="large">Tab 1 Child {{ $props.id }}</ion-title>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-item router-link="child-two" id="child-two">
|
<ion-item router-link="childone" id="child-one">
|
||||||
|
<ion-label>Tab 1 Child 1</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item router-link="childtwo" id="child-two">
|
||||||
<ion-label>Tab 1 Child 2</ion-label>
|
<ion-label>Tab 1 Child 2</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
@ -37,6 +41,7 @@ import {
|
|||||||
} from '@ionic/vue';
|
} from '@ionic/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
props: { id: String },
|
||||||
components: {
|
components: {
|
||||||
IonButtons,
|
IonButtons,
|
||||||
IonBackButton,
|
IonBackButton,
|
@ -53,15 +53,15 @@ describe('Routing', () => {
|
|||||||
cy.visit('http://localhost:8080/routing');
|
cy.visit('http://localhost:8080/routing');
|
||||||
|
|
||||||
cy.get('#parameter-abc').click();
|
cy.get('#parameter-abc').click();
|
||||||
cy.ionPageVisible('routingparameter');
|
cy.ionPageVisible('routingparameter-abc');
|
||||||
cy.get('[data-pageid=routingparameter] #parameter-value').should('have.text', 'abc');
|
cy.get('[data-pageid=routingparameter-abc] #parameter-value').should('have.text', 'abc');
|
||||||
cy.ionBackClick('routingparameter');
|
cy.ionBackClick('routingparameter-abc');
|
||||||
|
|
||||||
cy.ionPageDoesNotExist('routingparameter');
|
cy.ionPageDoesNotExist('routingparameter-abc');
|
||||||
|
|
||||||
cy.get('#parameter-xyz').click();
|
cy.get('#parameter-xyz').click();
|
||||||
cy.ionPageVisible('routingparameter');
|
cy.ionPageVisible('routingparameter-xyz');
|
||||||
cy.get('[data-pageid=routingparameter] #parameter-value').should('have.text', 'xyz');
|
cy.get('[data-pageid=routingparameter-xyz] #parameter-value').should('have.text', 'xyz');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/22359
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/22359
|
||||||
@ -69,7 +69,7 @@ describe('Routing', () => {
|
|||||||
cy.visit('http://localhost:8080/routing');
|
cy.visit('http://localhost:8080/routing');
|
||||||
|
|
||||||
cy.get('#parameter-abc').click();
|
cy.get('#parameter-abc').click();
|
||||||
cy.ionPageVisible('routingparameter');
|
cy.ionPageVisible('routingparameter-abc');
|
||||||
|
|
||||||
cy.get('#parameter-view').click();
|
cy.get('#parameter-view').click();
|
||||||
|
|
||||||
@ -149,32 +149,32 @@ describe('Routing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/22658
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/22658
|
||||||
it('should select correct leaving view when navigating between paramter urls', () => {
|
it('should select correct leaving view when navigating between parameter urls', () => {
|
||||||
cy.visit('http://localhost:8080');
|
cy.visit('http://localhost:8080');
|
||||||
|
|
||||||
cy.routerPush('/routing/123');
|
cy.routerPush('/routing/123');
|
||||||
cy.ionPageVisible('routingparameter');
|
cy.ionPageVisible('routingparameter-123');
|
||||||
cy.ionPageHidden('home');
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
cy.routerPush('/routing/456');
|
cy.routerPush('/routing/456');
|
||||||
cy.ionPageVisible('routingparameter');
|
cy.ionPageVisible('routingparameter-456');
|
||||||
cy.ionPageHidden('home');
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
cy.routerPush('/navigation');
|
cy.routerPush('/navigation');
|
||||||
cy.ionPageVisible('navigation');
|
cy.ionPageVisible('navigation');
|
||||||
cy.ionPageHidden('routingparameter');
|
cy.ionPageHidden('routingparameter-456');
|
||||||
|
|
||||||
cy.routerPush('/routing/789');
|
cy.routerPush('/routing/789');
|
||||||
cy.ionPageVisible('routingparameter');
|
cy.ionPageVisible('routingparameter-789');
|
||||||
cy.ionPageHidden('home');
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
cy.routerPush('/routing/000');
|
cy.routerPush('/routing/000');
|
||||||
cy.ionPageVisible('routingparameter');
|
cy.ionPageVisible('routingparameter-000');
|
||||||
cy.ionPageHidden('home');
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
cy.routerPush('/navigation');
|
cy.routerPush('/navigation');
|
||||||
cy.ionPageVisible('navigation');
|
cy.ionPageVisible('navigation');
|
||||||
cy.ionPageHidden('routingparameter');
|
cy.ionPageHidden('routingparameter-000');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/22528
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/22528
|
||||||
@ -191,6 +191,24 @@ describe('Routing', () => {
|
|||||||
|
|
||||||
cy.ionBackButtonHidden('home');
|
cy.ionBackButtonHidden('home');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/22662
|
||||||
|
it('should push a new instance of a parameterized page so there is a transition', () => {
|
||||||
|
cy.visit('http://localhost:8080');
|
||||||
|
|
||||||
|
cy.routerPush('/routing/123');
|
||||||
|
cy.ionPageVisible('routingparameter-123');
|
||||||
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
|
cy.routerPush('/routing/456');
|
||||||
|
cy.ionPageVisible('routingparameter-456');
|
||||||
|
cy.ionPageHidden('routingparameter-123');
|
||||||
|
|
||||||
|
cy.ionBackClick('routingparameter-456');
|
||||||
|
|
||||||
|
cy.ionPageVisible('routingparameter-123')
|
||||||
|
cy.ionPageDoesNotExist('routingparameter-456');
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Routing - Swipe to Go Back', () => {
|
describe('Routing - Swipe to Go Back', () => {
|
||||||
|
@ -50,7 +50,6 @@ Cypress.Commands.add('ionPageVisible', (pageId) => {
|
|||||||
Cypress.Commands.add('ionPageHidden', (pageId) => {
|
Cypress.Commands.add('ionPageHidden', (pageId) => {
|
||||||
cy.get(`div.ion-page[data-pageid=${pageId}]`)
|
cy.get(`div.ion-page[data-pageid=${pageId}]`)
|
||||||
.should('have.class', 'ion-page-hidden')
|
.should('have.class', 'ion-page-hidden')
|
||||||
.should('have.length', 1)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Cypress.Commands.add('ionBackClick', (pageId) => {
|
Cypress.Commands.add('ionBackClick', (pageId) => {
|
||||||
|
@ -392,6 +392,8 @@ describe('Routing', () => {
|
|||||||
router.push('/page/2');
|
router.push('/page/2');
|
||||||
await waitForRouter();
|
await waitForRouter();
|
||||||
|
|
||||||
expect(page.props()).toEqual({ id: '2' });
|
const pageAgain = wrapper.findAllComponents(Page);
|
||||||
|
expect(pageAgain[0].props()).toEqual({ id: '1' });
|
||||||
|
expect(pageAgain[1].props()).toEqual({ id: '2' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user