From: Eduardo San Martin Morote Date: Wed, 1 May 2019 13:52:00 +0000 (+0200) Subject: feat: resolve async components X-Git-Tag: v4.0.0-alpha.0~423 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bfdc0c49021af03791e3ad1a8bcfb94bac6daf5e;p=thirdparty%2Fvuejs%2Frouter.git feat: resolve async components --- diff --git a/__tests__/per-component-before-guards.spec.js b/__tests__/per-component-before-guards.spec.js index 2c215cdc..2aa8e4d5 100644 --- a/__tests__/per-component-before-guards.spec.js +++ b/__tests__/per-component-before-guards.spec.js @@ -65,9 +65,28 @@ describe('navigation guards', () => { expect(beforeRouteEnter).toHaveBeenCalledTimes(1) }) - it.skip('calls beforeEnter guards on replace', () => {}) + it('resolves async components before guarding', async () => { + const spy = jest.fn((to, from, next) => next()) + const component = { + template: `
`, + beforeRouteEnter: spy, + } + const [promise, resolve] = fakePromise() + const router = createRouter({ + routes: [...routes, { path: '/async', component: () => promise }], + }) + const pushPromise = router.push('/async') + expect(spy).not.toHaveBeenCalled() + resolve(component) + await pushPromise + + expect(spy).toHaveBeenCalledTimes(1) + }) + + it.skip('calls beforeRouteEnter guards on replace', () => {}) + it.skip('does not call beforeRouteEnter if we were already on the page', () => {}) - it.skip('waits before navigating', async () => { + it('waits before navigating', async () => { const [promise, resolve] = fakePromise() const router = createRouter({ routes }) beforeRouteEnter.mockImplementationOnce(async (to, from, next) => { diff --git a/src/router.ts b/src/router.ts index 466cb3c0..30765768 100644 --- a/src/router.ts +++ b/src/router.ts @@ -110,12 +110,18 @@ export class Router { // check in-component beforeRouteEnter guards = [] + // TODO: is it okay to resolve all matched component or should we do it in order await Promise.all( to.matched.map(async ({ component }) => { - // TODO: handle async routes - if (component.beforeRouteEnter) { + // TODO: cache async routes per record + const resolvedComponent = await (typeof component === 'function' + ? component() + : component) + if (resolvedComponent.beforeRouteEnter) { // TODO: handle the next callback - guards.push(guardToPromiseFn(component.beforeRouteEnter, to, from)) + guards.push( + guardToPromiseFn(resolvedComponent.beforeRouteEnter, to, from) + ) } }) ) diff --git a/src/types/index.ts b/src/types/index.ts index d8c326fa..33a950b9 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,5 +1,7 @@ import { HistoryQuery } from '../history/base' +type Lazy = () => Promise + export type TODO = any export type ListenerRemover = () => void @@ -67,7 +69,7 @@ export type RouteComponent = { // by any means export interface RouteRecord { path: string // | RegExp - component: RouteComponent + component: RouteComponent | Lazy name?: string beforeEnter?: NavigationGuard // props: PT