From: Eduardo San Martin Morote Date: Mon, 6 May 2019 19:24:14 +0000 (+0200) Subject: feat: call beforeRouteLeave with nested routes X-Git-Tag: v4.0.0-alpha.0~375 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ffae9737efcc0655b7c32901ee43a02ac4d878b;p=thirdparty%2Fvuejs%2Frouter.git feat: call beforeRouteLeave with nested routes --- diff --git a/__tests__/guards/component-beforeRouteLeave.spec.js b/__tests__/guards/component-beforeRouteLeave.spec.js index cee6670a..5c7697eb 100644 --- a/__tests__/guards/component-beforeRouteLeave.spec.js +++ b/__tests__/guards/component-beforeRouteLeave.spec.js @@ -22,6 +22,16 @@ function createRouter(options) { const Home = { template: `
Home
` } const Foo = { template: `
Foo
` } +const nested = { + parent: jest.fn(), + nestedEmpty: jest.fn(), + nestedA: jest.fn(), + nestedB: jest.fn(), + nestedAbs: jest.fn(), + nestedNested: jest.fn(), + nestedNestedFoo: jest.fn(), + nestedNestedParam: jest.fn(), +} const beforeRouteLeave = jest.fn() /** @type {RouteRecord[]} */ @@ -35,10 +45,64 @@ const routes = [ beforeRouteLeave, }, }, + { + path: '/nested', + component: { + ...Home, + beforeRouteLeave: nested.parent, + }, + children: [ + { + path: '', + name: 'nested-empty-path', + component: { ...Home, beforeRouteLeave: nested.nestedEmpty }, + }, + { + path: 'a', + name: 'nested-path', + component: { ...Home, beforeRouteLeave: nested.nestedA }, + }, + { + path: 'b', + name: 'nested-path-b', + component: { ...Home, beforeRouteLeave: nested.nestedB }, + }, + { + path: '/abs-nested', + name: 'absolute-nested', + component: { ...Home, beforeRouteLeave: nested.nestedAbs }, + }, + { + path: 'nested', + name: 'nested-nested', + component: { ...Home, beforeRouteLeave: nested.nestedNested }, + children: [ + { + path: 'foo', + name: 'nested-nested-foo', + component: { ...Home, beforeRouteLeave: nested.nestedNestedFoo }, + }, + { + path: 'param/:p', + name: 'nested-nested-param', + component: { ...Home, beforeRouteLeave: nested.nestedNestedParam }, + }, + ], + }, + ], + }, ] -beforeEach(() => { +function resetMocks() { beforeRouteLeave.mockReset() + for (const key in nested) { + nested[key].mockReset() + nested[key].mockImplementation(noGuard) + } +} + +beforeEach(() => { + resetMocks() }) describe('beforeRouteLeave', () => { @@ -61,6 +125,55 @@ describe('beforeRouteLeave', () => { expect(beforeRouteLeave).toHaveBeenCalledTimes(1) }) + it('calls beforeRouteLeave guard on navigation between children', async () => { + const router = createRouter({ routes }) + await router.push({ name: 'nested-path' }) + resetMocks() + await router[navigationMethod]({ name: 'nested-path-b' }) + expect(nested.nestedEmpty).not.toHaveBeenCalled() + expect(nested.nestedAbs).not.toHaveBeenCalled() + expect(nested.nestedB).not.toHaveBeenCalled() + expect(nested.nestedNestedFoo).not.toHaveBeenCalled() + expect(nested.parent).not.toHaveBeenCalled() + expect(nested.nestedNested).not.toHaveBeenCalled() + expect(nested.nestedA).toHaveBeenCalledTimes(1) + expect(nested.nestedA).toHaveBeenCalledWith( + expect.objectContaining({ + name: 'nested-path-b', + fullPath: '/nested/b', + }), + expect.objectContaining({ + name: 'nested-path', + fullPath: '/nested/a', + }), + expect.any(Function) + ) + }) + + it.skip('calls beforeRouteLeave guard on navigation between children in order', async () => { + const router = createRouter({ routes }) + await router.push({ name: 'nested-nested-foo' }) + resetMocks() + let count = 0 + nested.nestedNestedFoo.mockImplementation((to, from, next) => { + expect(count++).toBe(0) + next() + }) + nested.nestedNested.mockImplementation((to, from, next) => { + expect(count++).toBe(1) + next() + }) + nested.parent.mockImplementation((to, from, next) => { + expect(count++).toBe(2) + next() + }) + + await router[navigationMethod]('/') + expect(nested.parent).toHaveBeenCalledTimes(1) + expect(nested.nestedNested).toHaveBeenCalledTimes(1) + expect(nested.nestedNestedFoo).toHaveBeenCalledTimes(1) + }) + it('works when a lazy loaded component', async () => { const router = createRouter({ routes: [ diff --git a/src/router.ts b/src/router.ts index 91e8e15d..669a99e5 100644 --- a/src/router.ts +++ b/src/router.ts @@ -168,9 +168,8 @@ export class Router { let guards: Lazy[] // TODO: is it okay to resolve all matched component or should we do it in order - // TODO: use only components that we are leaving (children) guards = await extractComponentsGuards( - from.matched, + from.matched.filter(record => to.matched.indexOf(record) < 0), 'beforeRouteLeave', to, from