Vue
Install the adapter alongside Vue 3.2 or newer:
pnpm add @omni-async/vue @vue/runtime-core
Query
<script setup lang="ts">
import { useQuery } from "@omni-async/vue";
const users = useQuery(
async (team: string) => {
const response = await fetch(`/api/teams/${team}/users`);
if (!response.ok) throw new Error("Unable to load users");
return response.json() as Promise<string[]>;
},
{ initial: () => [] },
);
</script>
<template>
<button :disabled="users.loading.value" @click="users.trigger('platform')">Load users</button>
</template>
The result fields are Vue refs. useAsync invalidates active requests when its current effect scope is disposed.
Shared data ref
Vue queries can write into an existing ref:
const query = useQuery(loadUsers, {
data: shallowRef<User[]>([]),
});
query.data.value.push(newUser);
await query.trigger();
query.data is the exact writable ref passed in data. Manual changes are immediately visible, an
accepted successful request replaces its value, and a rejected request preserves its current value.
A later success can therefore overwrite manual edits.
The provided ref is the query's data storage, including after manual changes. Use initial instead
when the composable should own read-only computed data.