Tutorial

Using Asynchronous Computed Properties in Vue.js

Vue.js

While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

Computed properties in Vue are great. They let you perform complex operations or data formatting while maximizing performance with dependency calculations that only update the view when a dependency changes. But alas, they are entirely synchronous.

Thankfully, there is a plugin for that. 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.

Installation

vue-async-computed can be installed through yarn or npm.

# Yarn
$ yarn add vue-async-computed
# NPM
$ npm install vue-async-computed --save

Then, in your app bootstrap, make sure you enable the plugin.

main.js
import Vue from 'vue';
import AsyncComputed from 'vue-async-computed'
import App from 'App.vue';

Vue.use(AsyncComputed);

new Vue({
  el: '#app',
  render: h => h(App)
});

Usage

There are only a couple differences between standard computed properties and asynchronous ones.

  • Async properties cannot have setters.
  • Until the promise resolves, the value is null unless the default option is set. [See the Options section]

In most cases, you can just treat them as computed properties that return a Promise

MyComponent.vue
<template>
  <!-- myResolvedValue will become "*Fancy* Resolved Value!" after one second. -->
  <h2>Asynchronous Property {{myResolvedValue}}</p>
</template>

<script>
export default {
  asyncComputed: {
    myResolvedValue() {
      return new Promise((resolve, reject) => {
        setTimeout(() => resolve('*Fancy* Resolved Value!'), 1000)
      })
    }
  }
}
</script>

With ES7 / ES2016 async / await, this becomes even easier!

MyComponent.vue
<template>
  <!-- myResolvedValue will become "*Fancy* Resolved Value!" after one second. -->
  <h2>Asynchronous Property {{myResolvedValue}}</p>
</template>

<script>
function fancinessComesLater() {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve('*Fancy* Resolved Value!'), 1000)
  })
}

export default {
  asyncComputed: {
    async myResolvedValue() {
      return await fancinessComesLater()
    }
  }
}
</script>

Options

Setting a default value

Before a promise resolves, the default value is null. If you’d like it to be something else, you can use an object with a get() function and a default: val | default: Function property.

MyComponent.vue
<template>
  <!-- myResolvedValue be "No fanciness" until it resolves. -->
  <h2>Asynchronous Property {{myResolvedValue}}</p>
</template>

<script>
export default {
  asyncComputed: {
    myResolvedValue: {
      get () {
        return new Promise((resolve, reject) => {
          setTimeout(() => resolve('*Fancy* Resolved Value!'), 1000)
        })
      },
      default: 'No fanciness'
    }
  }
}
</script>

0 Comments

Creative Commons License