A simple useLoading composable for your Vue 3 projects

Search for a command to run...

No comments yet. Be the first to comment.
Hey guys, An update after I posted the “Laravel Excel: How to append rows to an existing Excel file“ a while back. This post will give you another solution and probably a better way to export that fits every case. Problems Previously, when trying to ...

Hey guys, An easy topic for today! Make something a default (e.g., category, product, campaign, etc). Let’s go with the categories table for the examples. Let’s say we only want one category to be the default one. And find out which is the optimal wa...
Hey guys, Probably a chapter 2 of this https://sethphat.dev/why-is-wordpress-still-an-awesome-cms blog post, haha. Here was the story: I’ve been spending like 2 days figuring out which CMS I want to use for my new blog (for my new hobby lol) Let’s se...

Hey guys, Well damn, it has been a while since my last post lol, lazy & busy. But here I am, back to write useful tips for y’all 🥹 Let us do some exporting tasks for today, using Laravel Excel to export XLSX (yeah CSV is so 2010 lol). But, append mo...

Hey guys, Recently, I just bought Herd PRO (a yearly subscription). I’ve been using the basic Herd since the first release. So, my latest work required interaction with S3 storage, there are several ways to achieve that in the local env: Use Cloud (...

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 ❤️.
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.
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,
};
};
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();
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 🛡️.
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...
And that's that, I hope you will like the useLoading composable. I really like the HoF withLoading above.
Thanks for reading!