Composables
Composables
Section titled “Composables”Composables are reusable composition functions that encapsulate and reuse stateful logic.
Overview
Section titled “Overview”IONFLOW uses Vue 3 Composition API composables (similar to React hooks) for:
- Shared reactive state
- Reusable business logic
- Data fetching patterns
- UI behaviors
Available Composables
Section titled “Available Composables”| Composable | Location | Description |
|---|---|---|
useDataTableParams | src/hooks/data.table.params.ts | DataTable pagination and filtering |
useThemeColor | src/hooks/useThemeColor.ts | Theme color management |
useDataTableParams
Section titled “useDataTableParams”Manages DataTable state including pagination, sorting, and filtering.
Import
Section titled “Import”import { useDataTableParams } from '@/hooks/data.table.params';const { first, rows, sortField, sortOrder, filters, onPage, onSort, onFilter, queryParams,} = useDataTableParams();Returns
Section titled “Returns”| Property | Type | Description |
|---|---|---|
first | Ref<number> | First row index |
rows | Ref<number> | Rows per page |
sortField | Ref<string> | Sort field name |
sortOrder | Ref<number> | Sort direction (1/-1) |
filters | Ref<object> | Filter values |
onPage | (event) => void | Page change handler |
onSort | (event) => void | Sort change handler |
onFilter | (event) => void | Filter change handler |
queryParams | ComputedRef | API query parameters |
Example
Section titled “Example”<template> <DataTable :value="data" :first="first" :rows="rows" :sortField="sortField" :sortOrder="sortOrder" :filters="filters" @page="onPage" @sort="onSort" @filter="onFilter" paginator lazy > <!-- columns --> </DataTable></template>
<script setup lang="ts">import { useDataTableParams } from '@/hooks/data.table.params';import { useQuery } from '@tanstack/vue-query';
const { first, rows, sortField, sortOrder, filters, onPage, onSort, onFilter, queryParams,} = useDataTableParams();
const { data } = useQuery({ queryKey: ['items', queryParams], queryFn: () => fetchItems(queryParams.value),});</script>useThemeColor
Section titled “useThemeColor”Manages application theme (light/dark mode).
Import
Section titled “Import”import { useThemeColor } from '@/hooks/useThemeColor';const { isDark, toggle, setTheme } = useThemeColor();Returns
Section titled “Returns”| Property | Type | Description |
|---|---|---|
isDark | Ref<boolean> | Dark mode state |
toggle | () => void | Toggle theme |
setTheme | (dark: boolean) => void | Set specific theme |
Creating Composables
Section titled “Creating Composables”When to Create
Section titled “When to Create”Create a composable when:
- Logic is used in 2+ components
- State needs to be shared across components
- Complex reactive logic needs encapsulation
Naming Convention
Section titled “Naming Convention”- Prefix with
use - Use camelCase
- Be descriptive
// ✅ Good namesuseFlowBuilderuseConnectionStatususeFormValidation
// ❌ Bad namesflowBuilderhandleConnectionvalidateStructure
Section titled “Structure”import { ref, computed, onMounted, onUnmounted } from 'vue';
type UseExampleOptions = { immediate?: boolean;};
export function useExample(options: UseExampleOptions = {}) { // State const data = ref<Data | null>(null); const loading = ref(false); const error = ref<Error | null>(null);
// Computed const hasData = computed(() => data.value !== null);
// Methods const fetch = async () => { loading.value = true; try { data.value = await fetchData(); } catch (e) { error.value = e as Error; } finally { loading.value = false; } };
const reset = () => { data.value = null; error.value = null; };
// Lifecycle onMounted(() => { if (options.immediate) { fetch(); } });
// Return public API return { data, loading, error, hasData, fetch, reset, };}File Location
Section titled “File Location”Place composables in src/hooks/:
src/hooks/├── data.table.params.ts├── useThemeColor.ts└── [composable].tsBest Practices
Section titled “Best Practices”Do’s ✅
Section titled “Do’s ✅”- Return reactive refs
- Clean up side effects in
onUnmounted - Type all parameters and returns
- Handle errors gracefully
- Document public API
Don’ts ❌
Section titled “Don’ts ❌”- Don’t use
anytypes - Don’t mutate props
- Don’t forget cleanup
- Don’t make too many responsibilities