I just started learning Vue3 by making a project where I want to fetch some data and render it (gasp! no way). It's easy to make a count increment with the basics of ref() and click handlers, but there were no simple examples of fetching some data, storing it to a reactive var, and rendering it. There are better ways to do this, but I learn best by getting something served and HOT reloading.
#how to
In SFCs you have to import the normal hooks that you have in Vue2:
<script lang="ts">import {(defineComponent, ref, onMounted)} from 'vue'</script>
Next, use defineComponent() which is a macro that can infer prop types and is the way to go if using TypeScript (I think).
export default defineComponent({ setup() { // everything happens here },});
In the body of setup you start by defining which reactive variables you want to assign your data to and eventually render. I am using homebrew's api, hence the names:
const brewData = ref<any[] | null>(null);const loading = ref<boolean>(true);const error = ref<string | null>(null);
Then, make a fetching fn like you would normally with one caveat. When assigning the data to the reactive ref you need to tack on .value:
async function fetchAllFormulae(): Promise<void> { const res = await fetch("https://formulae.brew.sh/api/formula.json"); const body = await res.json(); if (body) brewData.value = body; // THE CAVEAT :warning:}
Then in the mounted hook, call ur fn:
onMounted(async (): Promise<void> => await fetchAllFormulae());
And finally you have to return anything you want to use in the template:
return { brewData, loading, error };
Rendering is the same as in Vue2:
<div v-for="item in brewData"> <Card :item="item" /></div>
#Summary
- declare whatever the var the data will be assigned to using
ref(null) - put everything in a
setupbody - when assigning use your data-variable-name +
.value - call it within an
onMountedfn - return it at the end of all this
- render as normal
#Full Example
<script lang="ts">import { defineComponent, ref, onMounted } from 'vue'export default defineComponent({ setup() { const brewData = ref<any[] | null>(null) const loading = ref<boolean>(true) const error = ref<string | null>(null) async function fetchAllFormulae(): Promise<void> { const res = await fetch('https://formulae.brew.sh/api/formula.json') const body = await res.json() if (body) brewData.value = body } onMounted(async (): Promise<void> => await fetchAllFormulae()) return { brewData, loading, error } }})</script>
<template> <div v-if="!loading && brewData && brewData.length > 0"> <div v-fo="item in brewData"> <Card :ite="item" /> </div> <!-- use the loading, error variables here to provide a GORG ux for your u --> </div></template>