A simple useLoading composable for your Vue 3 projects

Hey guys,
Wanna share with you all a simple Vue composable function that lies in every Vue project of mine 😎.
Please meet the useLoading 🚀 A simple reusable composable that handles loading state flawlessly for you ❤️.
Before "useLoading", before composable
I (and most of us) have been using this kind of approach before composable 🤣
const isLoading = ref(false);
const loadUsers = async () => {
isLoading.value = true;
const res = await getUsers().catch(() => undefined)); // catch to avoid throw
isLoading.value = false;
users.value = res?.users ?? [];
};
onMounted(loadUsers);
So before when composable wasn't a thing, we likely had to copy/paste to every component that needed the isLoading indicator.
Vue's useLoading composable
With the composable introduced in Vue 3. It allows us to create multiple reusable pieces.
So I created this for my projects this bad boy. useLoading composable is a global one and can be reused everywhere.
// src/composables/useLoading.ts
import { ref } from 'vue';
export const useLoading = (initializedState = false) => {
const isLoading = ref(initializedState);
const startLoading = () => {
isLoading.value = true;
};
const stopLoading = () => {
isLoading.value = false;
};
const withLoading = (handler: () => Promise<void>) => async () => {
if (isLoading.value) {
return;
}
startLoading();
await handler().catch((err) => console.error(err));
stopLoading();
};
return {
isLoading,
startLoading,
stopLoading,
withLoading,
};
};
Default usage
By default, you can manually trigger startLoading and stopLoading, then use isLoading to check the state.
const { isLoading, startLoading, stopLoading } = useLoading();
startLoading();
// do something so long here
stopLoading();
HoF: withLoading
The awesomeness comes from this bad boy 😎. Having a high-order function to wrap our logic/handlers there and it's automatically triggered startLoading on start and stopLoading on finished.
const { isLoading, withLoading } = useLoading();
const loadUsers = withLoading(async () => {
const res = await getUsers().catch(() => undefined));
users.value = res.users ?? [];
});
onMounted(loadUsers);
Not to mention, the withLoading will not trigger another call if isLoading === true , thus ensuring we don't dispatch a lot of API calls/handlers/etc by mistake 🛡️.
Moving forward
Not only useLoading, but also there are several cases which you could create as a composable and reuse:
useError(error from API, error from FE, etc)useValidation(simple frontend validation)useRouteParams(return the Vue's router params in strict types)useRouteSearchParams(same as above but for URL Search Params aka GET params)and many more...
Closing topic
And that's that, I hope you will like the useLoading composable. I really like the HoF withLoading above.
Thanks for reading!



