Skip to content

Commit 2f54bc1

Browse files
authoredMar 16, 2021
fix(vue): passing params as props are correctly updated when switching pages (#23049)
resolves #23043
1 parent 2a253a1 commit 2f54bc1

File tree

2 files changed

+121
-1
lines changed

2 files changed

+121
-1
lines changed
 

‎packages/vue-router/src/viewStacks.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,31 @@ export const createViewStacks = (router: Router) => {
2323
}
2424

2525
const findViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, useDeprecatedRouteSetup: boolean = false) => {
26-
return findViewItemByPath(routeInfo.pathname, outletId, false, useDeprecatedRouteSetup);
26+
let viewItem = findViewItemByPath(routeInfo.pathname, outletId, false, useDeprecatedRouteSetup);
27+
28+
/**
29+
* Given a route such as /path/:id,
30+
* going from /page/1 to /home
31+
* to /page/2 will cause the same
32+
* view item from /page/1 to match
33+
* for /page/2 so we need to make
34+
* sure any params get updated.
35+
* Not normally an issue for accessing
36+
* the params via useRouter from vue-router,
37+
* but when passing params as props not doing
38+
* this would cause the old props to show up.
39+
*/
40+
if (viewItem && viewItem.params !== routeInfo.params) {
41+
/**
42+
* Clear the props function result
43+
* as the value may have changed due
44+
* to different props.
45+
*/
46+
delete viewItem.vueComponentData.propsFunctionResult;
47+
viewItem.params = routeInfo.params;
48+
}
49+
50+
return viewItem;
2751
}
2852

2953
const findLeavingViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: number, mustBeIonRoute: boolean = true, useDeprecatedRouteSetup: boolean = false) => {

‎packages/vue/test-app/tests/unit/routing.spec.ts

+96
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,100 @@ describe('Routing', () => {
262262
expect(wrapper.findComponent(Tab1).exists()).toBe(true);
263263
expect(wrapper.findComponent(Tab2).exists()).toBe(false);
264264
});
265+
266+
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23043
267+
it('should show the latest props passed to a route', async () => {
268+
const Page1 = {
269+
...BasePage,
270+
props: {
271+
title: { type: String, default: 'Default Title' }
272+
}
273+
};
274+
275+
const Home = {
276+
...BasePage
277+
}
278+
279+
const router = createRouter({
280+
history: createWebHistory(process.env.BASE_URL),
281+
routes: [
282+
{ path: '/', component: Home },
283+
{ path: '/:title', component: Page1, props: true }
284+
]
285+
});
286+
287+
router.push('/');
288+
await router.isReady();
289+
const wrapper = mount(App, {
290+
global: {
291+
plugins: [router, IonicVue]
292+
}
293+
});
294+
295+
router.push('/abc');
296+
await waitForRouter();
297+
298+
const cmp = wrapper.findComponent(Page1);
299+
expect(cmp.props()).toEqual({ title: 'abc' });
300+
301+
router.back();
302+
await waitForRouter();
303+
304+
router.push('/xyz');
305+
await waitForRouter();
306+
307+
const cmpAgain = wrapper.findComponent(Page1);
308+
expect(cmpAgain.props()).toEqual({ title: 'xyz' });
309+
});
310+
311+
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23043
312+
it('should call the props function again when params change', async () => {
313+
const Page1 = {
314+
...BasePage,
315+
props: {
316+
title: { type: String, default: 'Default Title' }
317+
}
318+
};
319+
320+
const Home = {
321+
...BasePage
322+
}
323+
324+
const propsFn = jest.fn((route) => {
325+
return { title: `${route.params.id} Title` }
326+
});
327+
328+
const router = createRouter({
329+
history: createWebHistory(process.env.BASE_URL),
330+
routes: [
331+
{ path: '/myPath/:id', component: Page1, props: propsFn },
332+
{ path: '/', component: Home }
333+
]
334+
});
335+
336+
router.push('/');
337+
await router.isReady();
338+
const wrapper = mount(App, {
339+
global: {
340+
plugins: [router, IonicVue]
341+
}
342+
});
343+
344+
router.push('/myPath/123');
345+
await waitForRouter();
346+
347+
const cmp = wrapper.findComponent(Page1);
348+
expect(propsFn.mock.calls.length).toBe(1);
349+
expect(cmp.props()).toEqual({ title: '123 Title' });
350+
351+
router.back();
352+
await waitForRouter();
353+
354+
router.push('/myPath/abc');
355+
await waitForRouter();
356+
357+
expect(propsFn.mock.calls.length).toBe(2);
358+
const cmpAgain = wrapper.findComponent(Page1);
359+
expect(cmpAgain.props()).toEqual({ title: 'abc Title' });
360+
});
265361
});

0 commit comments

Comments
 (0)
Please sign in to comment.