fix(vue): passing params as props are correctly updated when switching pages (#23049)

resolves #23043
This commit is contained in:
Liam DeBeasi
2021-03-16 09:31:45 -04:00
committed by GitHub
parent 2a253a1d33
commit 2f54bc1469
2 changed files with 121 additions and 1 deletions

View File

@ -23,7 +23,31 @@ export const createViewStacks = (router: Router) => {
} }
const findViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, useDeprecatedRouteSetup: boolean = false) => { const findViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, useDeprecatedRouteSetup: boolean = false) => {
return findViewItemByPath(routeInfo.pathname, outletId, false, useDeprecatedRouteSetup); let viewItem = findViewItemByPath(routeInfo.pathname, outletId, false, useDeprecatedRouteSetup);
/**
* 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, useDeprecatedRouteSetup: boolean = false) => { const findLeavingViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, mustBeIonRoute: boolean = true, useDeprecatedRouteSetup: boolean = false) => {

View File

@ -262,4 +262,100 @@ describe('Routing', () => {
expect(wrapper.findComponent(Tab1).exists()).toBe(true); expect(wrapper.findComponent(Tab1).exists()).toBe(true);
expect(wrapper.findComponent(Tab2).exists()).toBe(false); expect(wrapper.findComponent(Tab2).exists()).toBe(false);
}); });
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23043
it('should show the latest props passed to a route', async () => {
const Page1 = {
...BasePage,
props: {
title: { type: String, default: 'Default Title' }
}
};
const Home = {
...BasePage
}
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes: [
{ path: '/', component: Home },
{ path: '/:title', component: Page1, props: true }
]
});
router.push('/');
await router.isReady();
const wrapper = mount(App, {
global: {
plugins: [router, IonicVue]
}
});
router.push('/abc');
await waitForRouter();
const cmp = wrapper.findComponent(Page1);
expect(cmp.props()).toEqual({ title: 'abc' });
router.back();
await waitForRouter();
router.push('/xyz');
await waitForRouter();
const cmpAgain = wrapper.findComponent(Page1);
expect(cmpAgain.props()).toEqual({ title: 'xyz' });
});
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23043
it('should call the props function again when params change', async () => {
const Page1 = {
...BasePage,
props: {
title: { type: String, default: 'Default Title' }
}
};
const Home = {
...BasePage
}
const propsFn = jest.fn((route) => {
return { title: `${route.params.id} Title` }
});
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes: [
{ path: '/myPath/:id', component: Page1, props: propsFn },
{ path: '/', component: Home }
]
});
router.push('/');
await router.isReady();
const wrapper = mount(App, {
global: {
plugins: [router, IonicVue]
}
});
router.push('/myPath/123');
await waitForRouter();
const cmp = wrapper.findComponent(Page1);
expect(propsFn.mock.calls.length).toBe(1);
expect(cmp.props()).toEqual({ title: '123 Title' });
router.back();
await waitForRouter();
router.push('/myPath/abc');
await waitForRouter();
expect(propsFn.mock.calls.length).toBe(2);
const cmpAgain = wrapper.findComponent(Page1);
expect(cmpAgain.props()).toEqual({ title: 'abc Title' });
});
}); });