Vue-router: Enable component async loading

Created on 27 Jun 2019  ·  11Comments  ·  Source: vuejs/vue-router

What problem does this feature solve?

For now there is no full support for vue async components described here:

https://vuejs.org/v2/guide/components-dynamic-async.html#Handling-Loading-State

Solution presented in:
https://github.com/vuejs/vue-router/pull/2140
https://github.com/chrisvfritz/vue-enterprise-boilerplate/blob/master/src/router/routes.js
is solving problem only partially because of such construction beforeRouteEnter etc guards are not launched due to fact that component is resolved inside another component after route update

This problem is also mentioned here:
https://forum.vuejs.org/t/vue-router-async-component-loading-error-components-never-shown/40618/2

What does the proposed API look like?

Update doc with information that this syntax is not working with vue-router.

need repro

All 11 comments

If as you said in https://github.com/vuejs/vue-router/pull/2140/files#r298066005 , the navigation guards do not work, provide a boiled down repro to show your point

https://codesandbox.io/s/vue-template-971d5

Go to the default path:

  • Loader component is mounted
  • beforeRouteEnter guard is not triggered
  • Target Component is mounted

Go to /component path:

  • Loader component is not mounted
  • beforeRouteEnter guard is triggered
  • Target Component is mounted

Due to docs syntax used in /component path should work fine but is not working properly.
Wrapping target Component into functional render component cause to vue-router ignore route guards.

Ah, I see now. Let me explain what happens: The loader only appears after navigation is confirmed, while the network request is waiting for the component. This is exactly what we want for guards, the whole point is to not use the component if the navigation is cancelled, which could eventually prevent a network request as well

So you can't handle component loading in vue-router the way described in documentation and this sentence should be removed, because it don't work as expected.

Note that you must use Vue Router 2.4.0+ if you wish to use the above syntax for route components.

I just said that you can:

The loader only appears after navigation is confirmed, while the network request is waiting for the component.

I don't understand the last statement as it's completely out of context, the factory syntax for lazy loaded components was introduced in 2.4.0, so you need at least that version of Vue to use it

So how achieve displaying loading during request for component or handle rejection of component import for example from bad internet connection and don't lose navigation guards? Now it seems to impossible.

Edit:
You can catch error on import(...) and display error component but still I have a problem with displaying loading during requesting for component.

There is an example about handling the waiting state in between navigations at https://github.com/chrisvfritz/vue-enterprise-boilerplate/blob/master/src/router/index.js

It's something that will improve in next version and we also need to provide a better documentation for that topic

Thank you. Good to hear that this will be improved in next version :)

https://codesandbox.io/s/vue-template-bys6q
Expected behaviour:
Display loading before resolving stub component.

I tried to handle loading by beforeEach and afterEach as you described but it's not working in proper way. Because vue-router is mounting Root element after resolving all hooks so after resolving child components and still we can't proper handle loading of components.

Yeah, that's because in the root Vue, you are displaying the router-view component. Instead of having the loading logic inside of your view component Root.vue, it should be at the root component. Like the example in the cli or in docs where we mount an App.vue component. That component is always displayed so you can display the logic there

So I have to display whole page loader? If I have several components like Root.vue mounted for higher paths and want display loader only on updated part of website can I do that some way?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gil0mendes picture gil0mendes  ·  3Comments

rr326 picture rr326  ·  3Comments

baijunjie picture baijunjie  ·  3Comments

Lyfme picture Lyfme  ·  3Comments

saman picture saman  ·  3Comments