All quizzesHard
Advanced Composables
Preview — 3 of 10 questions
What is required for a component with an async setup() to work correctly with <Suspense>?
javascript
<!-- AsyncUserProfile.vue — async setup component -->
<script setup>
const props = defineProps({ userId: String })
// Top-level await makes setup async
const user = await fetchUser(props.userId)
const posts = await fetchUserPosts(props.userId)
</script>
<template>
<div>{{ user.name }}: {{ posts.length }} posts</div>
</template>
<!-- Parent component -->
<template>
<Suspense>
<template #default>
<AsyncUserProfile :userId="userId" />
</template>
<template #fallback>
<div>Loading user profile...</div>
</template>
</Suspense>
</template>AThe component must be wrapped with defineAsyncComponent
BThe parent must use <Suspense> and the child must export an asyncData function
CThe setup() function must use await at the top level, and the component must be wrapped in <Suspense> in the parent
D<Suspense> only works with useAsyncData from Nuxt, not standalone Vue
How do you handle errors from async setup components within <Suspense>?
javascript
<!-- ErrorBoundary.vue -->
<script setup>
import { ref, onErrorCaptured } from 'vue'
const error = ref(null)
onErrorCaptured((err, instance, info) => {
error.value = err
return false // Prevents error propagation to parent
})
</script>
<template>
<div v-if="error" class="error-boundary">
<h2>Something went wrong</h2>
<p>{{ error.message }}</p>
</div>
<slot v-else />
</template>
<!-- Usage -->
<template>
<ErrorBoundary>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
</ErrorBoundary>
</template>AUse try/catch in the parent's setup()
BWrap <Suspense> in a component that implements onErrorCaptured — creating an error boundary
CUse onErrorCaptured hook in the parent wrapping component
DUse the error named slot of <Suspense>
What pattern allows a composable to accept reactive arguments that can be either a plain value or a ref?
javascript
import { computed, toValue, type MaybeRefOrGetter } from 'vue'
// Flexible composable — accepts ref, computed, getter, or plain value
function useDouble(count: MaybeRefOrGetter<number>) {
return computed(() => toValue(count) * 2)
}
// All of these work:
const a = useDouble(5) // plain value
const b = useDouble(ref(5)) // ref
const c = useDouble(computed(() => 5)) // computed ref
const d = useDouble(() => someRef.value) // getter function
// Pre-Vue 3.3 equivalent using unref():
import { unref } from 'vue'
function useDouble(count) {
return computed(() => unref(count) * 2)
// unref(x) = isRef(x) ? x.value : x (does not handle getter functions)
}AUsing toValue() (Vue 3.3+) or unref() — the MaybeRefOrGetter pattern
BUsing computed to wrap every argument inside the composable
CUsing shallowRef on every argument inside the composable
DUsing TypeScript generics to constrain the argument type at compile time
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.