New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add section about handling loading state to lazy-loading doc #2140

Open
wants to merge 1 commit into
base: dev
from
Open
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.
+49 −0
Diff settings

Always

Just for now

@@ -45,3 +45,52 @@ const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
```

webpack will group any async module with the same chunk name into the same async chunk.

### Handling Loading State

Async component factories can also [return an object](https://vuejs.org/v2/guide/components-dynamic-async.html#Handling-Loading-State), specifying alternative components to use when loading or if an error occurs. This is a great way to improve user experience on slow or intermittent connections.

Unfortunately, routes can currently only resolve to a single component in Vue Router. So to make this work, you'll need a helper function to create an intermediary component, like this:

```js
function lazyLoadView (AsyncView) {
const AsyncHandler = () => ({
component: AsyncView,
// A component to use while the component is loading.
loading: require('./Loading.vue').default,
// A fallback component in case the timeout is exceeded
// when loading the component.
error: require('./Timeout.vue').default,
// Delay before showing the loading component.
// Default: 200 (milliseconds).
delay: 400,
// Time before giving up trying to load the component.
// Default: Infinity (milliseconds).
timeout: 10000
})
return Promise.resolve({
This conversation was marked as resolved by posva

This comment has been minimized.

@posva

posva Apr 4, 2018

Member

Doesn't it work without returning a promise and just doing component: lazyLoadView(...)

This comment has been minimized.

@chrisvfritz

chrisvfritz Apr 4, 2018

Author Member

If the import(...) isn't behind a function to be evaluated later, won't all the chunks be downloaded at startup time, regardless of whether the user needs them?

This comment has been minimized.

@blake-newman

blake-newman Apr 4, 2018

Member

As what I know only on execution its fetched (always forget how it works)

This comment has been minimized.

@blake-newman

blake-newman Apr 4, 2018

Member

So ies needs to be in a function, so it is only fetched when needed

functional: true,
render (h, { data, children }) {
// Transparently pass any props or children
// to the view component.
return h(AsyncHandler, data, children)
}
})
}
```

Then you can pass the `import()` to `lazyLoadView` for smarter, lazy-loaded view components:

```js
const router = new VueRouter({
routes: [
{
path: '/foo',
component: () => lazyLoadView(import('./Foo.vue'))
}
]
})
```

> WARNING: Components loaded with this strategy will **not** have access to in-component guards, such as `beforeRouteEnter`, `beforeRouteUpdate`, and `beforeRouteLeave`. If you need to use these, you must either use route-level guards instead or lazy-load the component directly, without handling loading state.
ProTip! Use n and p to navigate between commits in a pull request.