|
2 | 2 |
|
3 | 3 | import { _Vue } from '../install' |
4 | 4 | import type Router from '../index' |
5 | | -import { warn } from '../util/warn' |
6 | 5 | import { inBrowser } from '../util/dom' |
7 | 6 | import { runQueue } from '../util/async' |
| 7 | +import { warn, isError } from '../util/warn' |
8 | 8 | import { START, isSameRoute } from '../util/route' |
| 9 | +import { |
| 10 | + flatten, |
| 11 | + flatMapComponents, |
| 12 | + resolveAsyncComponents |
| 13 | +} from '../util/resolve-components' |
9 | 14 |
|
10 | 15 | export class History { |
11 | 16 | router: Router; |
@@ -321,100 +326,3 @@ function poll ( |
321 | 326 | }, 16) |
322 | 327 | } |
323 | 328 | } |
324 | | - |
325 | | -function resolveAsyncComponents (matched: Array<RouteRecord>): Function { |
326 | | - return (to, from, next) => { |
327 | | - let hasAsync = false |
328 | | - let pending = 0 |
329 | | - let error = null |
330 | | - |
331 | | - flatMapComponents(matched, (def, _, match, key) => { |
332 | | - // if it's a function and doesn't have cid attached, |
333 | | - // assume it's an async component resolve function. |
334 | | - // we are not using Vue's default async resolving mechanism because |
335 | | - // we want to halt the navigation until the incoming component has been |
336 | | - // resolved. |
337 | | - if (typeof def === 'function' && def.cid === undefined) { |
338 | | - hasAsync = true |
339 | | - pending++ |
340 | | - |
341 | | - const resolve = once(resolvedDef => { |
342 | | - // save resolved on async factory in case it's used elsewhere |
343 | | - def.resolved = typeof resolvedDef === 'function' |
344 | | - ? resolvedDef |
345 | | - : _Vue.extend(resolvedDef) |
346 | | - match.components[key] = resolvedDef |
347 | | - pending-- |
348 | | - if (pending <= 0) { |
349 | | - next() |
350 | | - } |
351 | | - }) |
352 | | - |
353 | | - const reject = once(reason => { |
354 | | - const msg = `Failed to resolve async component ${key}: ${reason}` |
355 | | - process.env.NODE_ENV !== 'production' && warn(false, msg) |
356 | | - if (!error) { |
357 | | - error = isError(reason) |
358 | | - ? reason |
359 | | - : new Error(msg) |
360 | | - next(error) |
361 | | - } |
362 | | - }) |
363 | | - |
364 | | - let res |
365 | | - try { |
366 | | - res = def(resolve, reject) |
367 | | - } catch (e) { |
368 | | - reject(e) |
369 | | - } |
370 | | - if (res) { |
371 | | - if (typeof res.then === 'function') { |
372 | | - res.then(resolve, reject) |
373 | | - } else { |
374 | | - // new syntax in Vue 2.3 |
375 | | - const comp = res.component |
376 | | - if (comp && typeof comp.then === 'function') { |
377 | | - comp.then(resolve, reject) |
378 | | - } |
379 | | - } |
380 | | - } |
381 | | - } |
382 | | - }) |
383 | | - |
384 | | - if (!hasAsync) next() |
385 | | - } |
386 | | -} |
387 | | - |
388 | | -function flatMapComponents ( |
389 | | - matched: Array<RouteRecord>, |
390 | | - fn: Function |
391 | | -): Array<?Function> { |
392 | | - return flatten(matched.map(m => { |
393 | | - return Object.keys(m.components).map(key => fn( |
394 | | - m.components[key], |
395 | | - m.instances[key], |
396 | | - m, key |
397 | | - )) |
398 | | - })) |
399 | | -} |
400 | | - |
401 | | -function flatten (arr) { |
402 | | - return Array.prototype.concat.apply([], arr) |
403 | | -} |
404 | | - |
405 | | -// in Webpack 2, require.ensure now also returns a Promise |
406 | | -// so the resolve/reject functions may get called an extra time |
407 | | -// if the user uses an arrow function shorthand that happens to |
408 | | -// return that Promise. |
409 | | -function once (fn) { |
410 | | - let called = false |
411 | | - return function (...args) { |
412 | | - if (called) return |
413 | | - called = true |
414 | | - return fn.apply(this, args) |
415 | | - } |
416 | | -} |
417 | | - |
418 | | -function isError (err) { |
419 | | - return Object.prototype.toString.call(err).indexOf('Error') > -1 |
420 | | -} |
0 commit comments