iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Exercises

Three small Vue 3 components to lock in the Composition API.

Three short challenges

EXAMPLE
<!-- 1. Counter with a computed and watcher -->
<script setup lang='ts'>
import { ref, computed, watch } from 'vue';

const count = ref(0);
const doubled = computed(() => count.value * 2);

watch(count, (n, prev) => {
  console.log('went from', prev, 'to', n);
});
</script>

<template>
  <button @click='count++'>count: {{ count }}</button>
  <p>doubled: {{ doubled }}</p>
</template>


<!-- 2. v-model on a custom input -->
<!-- ChildInput.vue -->
<script setup lang='ts'>
const props = defineProps<{ modelValue: string }>();
const emit = defineEmits<(e: 'update:modelValue', value: string) => void>();
</script>

<template>
  <input
    :value='props.modelValue'
    @input='emit("update:modelValue", ($event.target as HTMLInputElement).value)'
  />
</template>


<!-- Parent.vue -->
<script setup lang='ts'>
import { ref } from 'vue';
import ChildInput from './ChildInput.vue';
const name = ref('');
</script>

<template>
  <ChildInput v-model='name' />
  <p>hello, {{ name || 'stranger' }}</p>
</template>


<!-- 3. Async list with Suspense + useFetch composable -->
<!-- useFetch.ts -->
import { ref } from 'vue';
export async function useFetch<T>(url: string) {
  const data = ref<T | null>(null);
  data.value = await fetch(url).then(r => r.json());
  return { data };
}


<!-- UserList.vue -->
<script setup lang='ts'>
import { useFetch } from './useFetch';
const { data } = await useFetch<{ id: number; name: string }[]>('/api/users');
</script>

<template>
  <ul>
    <li v-for='u in data' :key='u.id'>{{ u.name }}</li>
  </ul>
</template>


<!-- Parent uses Suspense -->
<template>
  <Suspense>
    <template #default><UserList /></template>
    <template #fallback>Loading...</template>
  </Suspense>
</template>

Why it matters

Composition API rewards extraction. Once you see useFetch / useCounter / useLocalStorage patterns in real apps, you stop reaching for Vuex/Pinia for things that should just be a composable.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// Fill in: <h1>{{ ____ }}</h1>
Try it Yourself »

Discussion

Loading…