Vue 3 is in beta and it’s subject to change.
Vue 3 is the up and coming version of Vue front end framework.
It builds on the popularity and ease of use of Vue 2.
In this article, we’ll look at how to add dynamic and async components with Vue 3.
Dynamic Components with keep-alive
The keep-alive
component lets us keep the state of the component even if we switched out of them.
For instance, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<button @click='currentComponent = "tab-home"'>home</button>
<button @click='currentComponent = "tab-post"'>post</button>
<button @click='currentComponent = "tab-archive"'>archive</button>
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</div>
<script>
const app = Vue.createApp({
data() {
return {
currentComponent: "tab-home"
};
}
});
app.component("tab-home", {
template: `
<div>
home
</div>
`
});
app.component("tab-post", {
data() {
return {
on: false
};
},
template: `
<div>
<button @click='on = !on'>toggle</button>
<p v-if='on'>post</p>
</div>
`
});
app.component("tab-archive", {
data() {
return {
on: false
};
},
template: `
<div>
<button @click='on = !on'>toggle</button>
<p v-if='on'>archive</p>
</div>
`
});
app.mount("#app");
</script>
</body>
</html>
We have the keep-alive
component to cache the state of dynamic components so that when we display it again after leaving it, we keep the same state as before.
So if the on
state is true
in tab-post
or tab-archive
, then on
will stay true
even if we switch back and forth between any component.
Without it, the on
state would be reset to the initial state.
Async Components
In larger apps, we may need to divide our app int smaller chunks and only load a component from the server when it’s needed.
We can do that with the Vue.defineAsyncComponent
method.
For example, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<async-comp></async-comp>
</div>
<script>
const app = Vue.createApp({});
const AsyncComp = Vue.defineAsyncComponent(
() =>
new Promise((resolve, reject) => {
resolve({
template: "<div>async component</div>"
});
})
);
app.component("async-comp", AsyncComp);
app.mount("#app");
</script>
</body>
</html>
to define an async component and use it.
We called Vue.defineAsyncComponent
with a callback that returns a promise that resolves to a component object.
We can pass the async component returned to the app.component
method with the name as the first argument and the async component object as the 2nd argument.
Then we can use it in our parent Vue instance’s template.
We can also import the component from somewhere else.
For example, we can write:
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
app.component('async-component', AsyncComp)
import
returns a promise that resolves to the Vue component so we achieve the same result.
We can also register the component locally by putting our async component in the components
property:
import { createApp, defineAsyncComponent } from 'vue'
createApp({
// ...
components: {
AsyncComponent: defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
}
})
Use with Suspense
Async components are suspensible by default.
That means we can pass it into the Suspenbse
component and use it.
To disable suspension, we can set suspensible
to false
in the async component.
Conclusion
We can define async components to load them asynchronously.
The keep-alive
component lets us keep the component’s state while switching between them.