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) => {
// 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)
+ )
}
})
)
import { HistoryQuery } from '../history/base'
+type Lazy<T> = () => Promise<T>
+
export type TODO = any
export type ListenerRemover = () => void
// by any means
export interface RouteRecord {
path: string // | RegExp
- component: RouteComponent
+ component: RouteComponent | Lazy<RouteComponent>
name?: string
beforeEnter?: NavigationGuard
// props: PT