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.
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>
ref(null)
setup
body.value
onMounted
fn<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-for="item in brewData">
<Card :item="item" />
</div>
<!-- use the loading, error variables here to provide a GORG ux for your u -->
</div>
</template>