]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat: resolve async components
authorEduardo San Martin Morote <posva13@gmail.com>
Wed, 1 May 2019 13:52:00 +0000 (15:52 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Wed, 1 May 2019 13:52:00 +0000 (15:52 +0200)
__tests__/per-component-before-guards.spec.js
src/router.ts
src/types/index.ts

index 2c215cdc7c934b755661fbe665440f0143cee7b7..2aa8e4d592462f102116f28594033510996c3b38 100644 (file)
@@ -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: `<div></div>`,
+      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) => {
index 466cb3c023bdc33dc98b9555328866ea3894a4fb..307657686c09ad0e0ad1d16e65f1829a32e591a1 100644 (file)
@@ -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)
+          )
         }
       })
     )
index d8c326fabdc4ffe2b63e459866f365a76e7c735e..33a950b9c17d37043dfc45a019a20f0cbd260e19 100644 (file)
@@ -1,5 +1,7 @@
 import { HistoryQuery } from '../history/base'
 
+type Lazy<T> = () => Promise<T>
+
 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<RouteComponent>
   name?: string
   beforeEnter?: NavigationGuard
   // props: PT