Skip to content
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
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 49 additions & 0 deletions docs/en/advanced/lazy-loading.md
Expand Up @@ -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) {
posva marked this conversation as resolved.
Show resolved Hide resolved
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({
posva marked this conversation as resolved.
Show resolved Hide resolved
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.