@@ -4,7 +4,7 @@ import type VueRouter from '../index'
4
4
import { warn } from '../util/warn'
5
5
import { inBrowser } from '../util/dom'
6
6
import { runQueue } from '../util/async'
7
- import { createRoute , isSameRoute } from '../util/route'
7
+ import { START , isSameRoute } from '../util/route'
8
8
9
9
export class History {
10
10
router : VueRouter ;
@@ -23,9 +23,7 @@ export class History {
23
23
this . router = router
24
24
this . base = normalizeBase ( base )
25
25
// start with a route object that stands for "nowhere"
26
- this . current = createRoute ( null , {
27
- path : '__vue_router_init__'
28
- } )
26
+ this . current = START
29
27
this . pending = null
30
28
}
31
29
@@ -43,7 +41,8 @@ export class History {
43
41
}
44
42
45
43
confirmTransition ( route : Route , cb : Function ) {
46
- if ( isSameRoute ( route , this . current ) ) {
44
+ const current = this . current
45
+ if ( isSameRoute ( route , current ) ) {
47
46
this . ensureURL ( )
48
47
return
49
48
}
@@ -65,15 +64,28 @@ export class History {
65
64
)
66
65
67
66
this . pending = route
68
- const redirect = location => this . push ( location )
69
- const iterator = ( hook , next ) => hook ( route , redirect , next )
67
+ const iterator = ( hook , next ) => {
68
+ if ( this . pending !== route ) return
69
+ hook ( route , current , ( to : any ) => {
70
+ if ( to === false ) {
71
+ // next(false) -> abort navigation, ensure current URL
72
+ this . ensureURL ( )
73
+ } else if ( typeof to === 'string' || typeof to === 'object' ) {
74
+ // next('/') or next({ path: '/' }) -> redirect
75
+ this . push ( to )
76
+ } else {
77
+ // confirm transition and pass on the value
78
+ next ( to )
79
+ }
80
+ } )
81
+ }
70
82
71
83
runQueue ( queue , iterator , ( ) => {
72
84
const postEnterCbs = [ ]
73
85
// wait until async components are resolved before
74
86
// extracting in-component enter guards
75
87
runQueue ( extractEnterGuards ( activated , postEnterCbs ) , iterator , ( ) => {
76
- if ( isSameRoute ( route , this . pending ) ) {
88
+ if ( this . pending === route ) {
77
89
this . pending = null
78
90
cb ( route )
79
91
this . router . app . $nextTick ( ( ) => {
@@ -146,12 +158,14 @@ function extractEnterGuards (matched: Array<RouteRecord>, cbs: Array<Function>):
146
158
return flatMapComponents ( matched , ( def , _ , match , key ) => {
147
159
const guard = def && def . beforeRouteEnter
148
160
if ( guard ) {
149
- return function routeEnterGuard ( route , redirect , next ) {
150
- return guard ( route , redirect , cb => {
151
- next ( )
152
- cb && cbs . push ( ( ) => {
153
- cb ( match . instances [ key ] )
154
- } )
161
+ return function routeEnterGuard ( to , from , next ) {
162
+ return guard ( to , from , cb => {
163
+ next ( cb )
164
+ if ( typeof cb === 'function' ) {
165
+ cbs . push ( ( ) => {
166
+ cb ( match . instances [ key ] )
167
+ } )
168
+ }
155
169
} )
156
170
}
157
171
}
@@ -166,14 +180,15 @@ function resolveAsyncComponents (matched: Array<RouteRecord>): Array<?Function>
166
180
// we want to halt the navigation until the incoming component has been
167
181
// resolved.
168
182
if ( typeof def === 'function' && ! def . options ) {
169
- return ( route , redirect , next ) => {
183
+ return ( to , from , next ) => {
170
184
const resolve = resolvedDef => {
171
185
match . components [ key ] = resolvedDef
172
186
next ( )
173
187
}
174
188
175
189
const reject = reason => {
176
190
warn ( false , `Failed to resolve async component ${ key } : ${ reason } ` )
191
+ next ( false )
177
192
}
178
193
179
194
const res = def ( resolve , reject )
0 commit comments