Computed properties in Vue let you perform complex operations or data formatting while maximizing performance with dependency calculations that only update the view when a dependency changes. This feature is synchronous.
However, the vue-async-computed
package allows you to create and consume asynchronous computed properties in your components by binding the resolved value of a Promise
to a component property.
To complete this tutorial, you will need:
Promise
, async
, and await
.This tutorial was verified with Node v15.10.0, npm
v7.6.0, vue
v2.6.11, and vue-async-computed
v3.9.0.
To quickly set up the project, this article will recommend using @vue/cli
.
Note: This article will take the approach of using npx
to avoid a global installation of @vue/cli
;
- npx @vue/cli create vue-async-computed-example --default
Navigate to the newly created project directory;
- cd vue-async-computed-example
vue-async-computed
can be installed through npm
with the following command:
- npm install vue-async-computed@3.9.0
Then, open the main.js
file with your code editor. Import and use vue-async-computed
:
import Vue from 'vue'
import AsyncComputed from 'vue-async-computed'
import App from './App.vue'
Vue.config.productionTip = false
Vue.use(AsyncComputed)
new Vue({
render: h => h(App),
}).$mount('#app')
At this point, you will have a new Vue project that supports vue-async-computed
.
asyncComputed
There are a few differences between standard computed
properties and asyncComputed
properties:
asyncComputed
properties cannot have setters.Promise
resolves, the value is null
unless the default
option is set.In most cases, you can just treat them as computed properties that return a Promise
.
Here is a sample component that uses asyncComputed
:
<template>
<div>
<h2>Asynchronous Property</h2>
<p>{{myResolvedValue}}</p>
</div>
</template>
<script>
/* eslint-disable no-unused-vars */
export default {
asyncComputed: {
myResolvedValue() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('Changed Value!'), 1000)
})
}
}
}
</script>
Warning: Depending on your eslint
rules, you may encounter a warning about reject
being defined but never used. For the purposes of this tutorial, you can work around this issue by disabling this rule: /* eslint-disable no-unused-vars */
.
This can be rewritten with ES7 / ES2016 async / await
:
<template>
<div>
<h2>Asynchronous Property</h2>
<p>{{myResolvedValue}}</p>
</div>
</template>
<script>
/* eslint-disable no-unused-vars */
function asyncChange() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('Changed Value!'), 1000)
})
}
export default {
asyncComputed: {
async myResolvedValue() {
return await asyncChange()
}
}
}
</script>
Save your changes to this file.
Thne, open the App.vue
file with your code editor. Modify this file to use your new component:
<template>
<div id="app">
<MyComponent/>
</div>
</template>
<script>
import MyComponent from './components/MyComponent.vue'
export default {
name: 'App',
components: {
MyComponent
}
}
</script>
Next, run the application:
- npm run serve
Observe the application in your web browser. There will be no default
message initially. After 1 second has elapsed, the message "Changed Value!"
will appear.
Before a Promise
resolves, the default value is null
. If you would like the default value to be something else, you can use an object with a get()
function and a default: val | default: Function
property.
Here is a sample component that uses a default
value:
<template>
<div>
<h2>Asynchronous Property</h2>
<p>{{myResolvedValue}}</p>
</div>
</template>
<script>
/* eslint-disable no-unused-vars */
export default {
asyncComputed: {
myResolvedValue: {
get() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('Changed Value!'), 1000)
})
},
default: 'No Changes!'
}
}
}
</script>
Save your changes to this file.
Next, run the application:
- npm run serve
Observe the application in your web browser. The default
message "No Changes"
will be present initially. After 1 second has elapsed, the message "Changed Value!"
will appear.
In this article, you applied vue-async-computed
to a Vue project to utilize asyncComputed
.
Some of the advantages and disadvantages of this package and decisions on why this functionality is not available in Vue core by default are captured in this GitHub issue.
If you’d like to learn more about Vue.js, check out our Vue.js topic page for exercises and programming projects.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.