vue3-async-compute demo

by andriika

HTML

<!doctype html>
<html lang="en">

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css">
    <script crossorigin="anonymous" src="https://unpkg.com/[email protected]"></script>
  </head>

  <body>
    <div id="app" class="section">
      <h1 class="title">Crypto Prices</h1>
      <div class="tabs">
        <ul>
          <li v-for="c in coins" :class="{'is-active': coin == c}" @click="coin = c"><a>{{c}}</a></li>
        </ul>
      </div>
      <pre>{{price}}</pre>
    </div>
  </body>

</html>

JavaScript

import * as AsyncComputed from "https://unpkg.com/[email protected]";

const asyncComputed = AsyncComputed.createPlugin({ ref: Vue.ref });

Vue.createApp({

    data() {
        return {
            coins: ['BTC', 'ETH', 'LTC', 'BNT'],
            coin: 'BTC',
        }
    },

}).use(asyncComputed, {

    async price(result) {
        result.value = `loading ${this.coin} price...`;
        result.value = await getPrice(this.coin);
    }

}).mount('#app');

// API

async function getPrice(coin) {
	await sleep(1000); // for better demo experience, we sleep here for 2 seconds
  const response = await fetch(`https://api.coinbase.com/v2/prices/${coin}-USD/buy`);
  const payload = await response.json();
  return payload.data;
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}