5.0 KiB
5.0 KiB
Global Loading State Usage Guide
This document explains how to use the global loading state system in your Vue app.
Overview
The loading system provides multiple ways to handle loading states:
- Global Loading Overlay - Shows over the entire app
- Component-specific Loading - For individual components like DataTable and Form
- Operation-specific Loading - For tracking specific async operations
Loading Store
Basic Usage
import { useLoadingStore } from "../../stores/loading";
const loadingStore = useLoadingStore();
// Set global loading
loadingStore.setLoading(true, "Processing...");
// Set component-specific loading
loadingStore.setComponentLoading("dataTable", true, "Loading data...");
// Use async wrapper
const data = await loadingStore.withLoading(
"fetchUsers",
() => Api.getUsers(),
"Fetching user data...",
);
Available Methods
setLoading(isLoading, message?)- Global loading statesetComponentLoading(componentName, isLoading, message?)- Component loadingstartOperation(operationKey, message?)- Start tracked operationstopOperation(operationKey)- Stop tracked operationwithLoading(operationKey, asyncFn, message?)- Async wrapperwithComponentLoading(componentName, asyncFn, message?)- Component async wrapper
Convenience Methods
startApiCall(apiName?)- Quick API loadingstopApiCall()- Stop API loadingstartDataTableLoading(message?)- DataTable loadingstopDataTableLoading()- Stop DataTable loadingstartFormLoading(message?)- Form loadingstopFormLoading()- Stop Form loading
DataTable Component
The DataTable component automatically integrates with the loading store:
<template>
<DataTable
:data="tableData"
:columns="columns"
tableName="clients"
:loading="customLoading"
loadingMessage="Custom loading message..."
emptyMessage="No clients found"
/>
</template>
<script setup>
// DataTable will automatically show loading when:
// 1. props.loading is true
// 2. Global loading store has loading for 'dataTable'
// 3. Global loading store has loading for props.tableName
// 4. Any global loading (if useGlobalLoading is true)
// You can also control it directly:
const tableRef = ref();
tableRef.value?.startLoading("Custom loading...");
tableRef.value?.stopLoading();
</script>
Form Component
The Form component also integrates with loading:
<template>
<Form
:fields="formFields"
formName="userForm"
:loading="customLoading"
loadingMessage="Saving user..."
@submit="handleSubmit"
/>
</template>
<script setup>
// Form will disable all inputs and show loading buttons when:
// 1. props.loading is true
// 2. Global loading store has loading for 'form'
// 3. Global loading store has loading for props.formName
// 4. Internal isSubmitting is true
// Control directly:
const formRef = ref();
formRef.value?.startLoading("Processing...");
formRef.value?.stopLoading();
</script>
API Integration Example
// In your page component
import { useLoadingStore } from "../../stores/loading";
const loadingStore = useLoadingStore();
// Method 1: Manual control
const loadData = async () => {
try {
loadingStore.startDataTableLoading("Loading clients...");
const data = await Api.getClients();
tableData.value = data;
} finally {
loadingStore.stopDataTableLoading();
}
};
// Method 2: Using wrapper (recommended)
const loadData = async () => {
const data = await loadingStore.withComponentLoading(
"clients",
() => Api.getClients(),
"Loading clients...",
);
tableData.value = data;
};
// Method 3: For global overlay
const performGlobalAction = async () => {
const result = await loadingStore.withLoading(
"globalOperation",
() => Api.performHeavyOperation(),
"Processing your request...",
);
return result;
};
Global Loading Overlay
The GlobalLoadingOverlay component shows automatically when global loading is active:
<!-- Already added to App.vue -->
<GlobalLoadingOverlay />
<!-- Customizable props -->
<GlobalLoadingOverlay
:globalOnly="false" <!-- Show for any loading, not just global -->
:minDisplayTime="500" <!-- Minimum display time in ms -->
/>
Best Practices
- Use component-specific loading for individual components
- Use global loading for app-wide operations (login, navigation, etc.)
- Use operation tracking for multiple concurrent operations
- Always use try/finally when manually controlling loading
- Prefer async wrappers over manual start/stop calls
- Provide meaningful loading messages to users
Error Handling
const loadData = async () => {
try {
const data = await loadingStore.withComponentLoading(
"clients",
() => Api.getClients(),
"Loading clients...",
);
tableData.value = data;
} catch (error) {
console.error("Failed to load clients:", error);
// Show error message to user
// Loading state is automatically cleared by the wrapper
}
};