useLoadedAction
Convenience wrapper around useLoaded for the common case of a single async action with its own loading flag. Returns a tuple of [wrappedAction, isLoading].
Demo
—
<script setup lang="ts">
import { ref } from 'vue';
import { useLoadedAction } from '@basmilius/common';
const result = ref('—');
const [save, isSaving] = useLoadedAction(async () => {
await new Promise(resolve => setTimeout(resolve, 1200));
result.value = `Saved at ${new Date().toLocaleTimeString()}`;
});
</script>
<template>
<div class="demo">
<button class="button" :disabled="isSaving" @click="save()">
{{ isSaving ? 'Saving…' : 'Save' }}
</button>
<p class="result">{{ result }}</p>
</div>
</template>
<style scoped>
.demo {
display: flex;
align-items: center;
gap: 14px;
padding: 24px;
border: 1px solid var(--vp-c-border);
border-radius: 12px;
background: var(--vp-c-bg-soft);
}
.button {
padding: 8px 16px;
border-radius: 8px;
background: var(--vp-c-brand-1);
font-weight: 600;
color: var(--vp-c-white);
}
.button:disabled {
opacity: .6;
}
.result {
margin: 0;
font-family: var(--vp-font-family-mono);
font-size: 14px;
color: var(--vp-c-text-2);
}
</style>Importing
ts
import { useLoadedAction } from '@basmilius/common';Usage
vue
<script setup lang="ts">
import { useLoadedAction, useService } from '@basmilius/common';
import { OrderService } from '@/services/OrderService';
const orders = useService(OrderService);
const [submit, isSubmitting] = useLoadedAction(async (id: number) => {
await orders.submit(id);
});
</script>
<template>
<button :disabled="isSubmitting" @click="submit(123)">
{{ isSubmitting ? 'Submitting...' : 'Submit' }}
</button>
</template>Use useLoaded directly when you need to track multiple actions under a single loading flag.
Type signature
ts
declare function useLoadedAction<T extends (...args: any[]) => Promise<any>>(
fn: T
): [T, ComputedRef<boolean>];