Skip to content

useTable Composable

useTable is a powerful Vue 3 composable designed for table data management in modern web applications. It provides a complete table solution including data fetching, intelligent caching, pagination control, search functionality, and multiple refresh strategies.

Features

  • Intelligent Caching - Efficient caching mechanism based on LRU algorithm
  • Debounced Search - Built-in debounce functionality for optimized search experience
  • Flexible Pagination - Complete pagination control and state management
  • Multiple Refresh Strategies - Smart refresh strategies for different business scenarios
  • Error Handling - Comprehensive error handling and recovery mechanisms

Quick Start

Basic Usage

vue
<template>
  <div>
    <!-- Table Component -->
    <ArtTable
      :loading="loading"
      :data="data"
      :columns="columns"
      :pagination="pagination"
      @pagination:size-change="handleSizeChange"
      @pagination:current-change="handleCurrentChange"
    />
  </div>
</template>

<script setup lang="ts">
import { useTable } from "@/composables/useTable";
import { fetchGetUserList } from "@/api/system-manage";

const {
  data,
  loading,
  columns,
  pagination,
  handleSizeChange,
  handleCurrentChange,
} = useTable({
  core: {
    apiFn: fetchGetUserList,
    apiParams: {
      current: 1,
      size: 20,
    },
    columnsFactory: () => [
      { prop: "id", label: "ID" },
      { prop: "name", label: "Name" },
      { prop: "email", label: "Email" },
    ],
  },
});
</script>

Advanced Usage

vue
<script setup lang="ts">
import { useTable, CacheInvalidationStrategy } from "@/composables/useTable";

const {
  // Data related
  data,
  loading,
  error,
  hasData,

  // Pagination related
  pagination,
  handleSizeChange,
  handleCurrentChange,

  // Search related
  searchParams,
  resetSearchParams,

  // Data operations
  getData,
  getDataDebounced,
  clearData,

  // Refresh strategies
  refreshData,
  refreshSoft,
  refreshCreate,
  refreshUpdate,
  refreshRemove,

  // Cache control
  cacheInfo,
  clearCache,
  clearExpiredCache,

  // Column configuration
  columns,
  columnChecks,
  addColumn,
  removeColumn,
  toggleColumn,
} = useTable<UserListItem>({
  // Core configuration
  core: {
    apiFn: UserService.fetchGetUserList,
    apiParams: {
      current: 1,
      size: 20,
      name: "",
      status: "",
    },
    excludeParams: ["daterange"],
    immediate: true,
    columnsFactory: () => [
      { prop: "name", label: "Name", sortable: true },
      { prop: "email", label: "Email" },
      { prop: "status", label: "Status", useSlot: true },
    ],
  },

  // Data processing
  transform: {
    dataTransformer: (records) => {
      return records.map((item) => ({
        ...item,
        statusText: item.status === 1 ? "Active" : "Inactive",
      }));
    },
  },

  // Performance optimization
  performance: {
    enableCache: true,
    cacheTime: 5 * 60 * 1000, // 5 minutes
    debounceTime: 300,
    maxCacheSize: 100,
  },

  // Lifecycle hooks
  hooks: {
    onSuccess: (data, response) => {
      console.log("Data loaded successfully:", data.length);
    },
    onError: (error) => {
      console.error("Loading failed:", error.message);
    },
    onCacheHit: (data, response) => {
      console.log("Cache hit:", data.length);
    },
  },
});

// Search functionality
const handleSearch = () => {
  Object.assign(searchParams, {
    name: "John",
    status: 1,
  });
  getData();
};

// Refresh after CRUD operations
const handleAdd = () => {
  // Return to first page after adding
  refreshCreate();
};

const handleEdit = () => {
  // Keep current page after editing
  refreshUpdate();
};

const handleDelete = () => {
  // Smart page handling after deletion
  refreshRemove();
};
</script>

API Reference

Configuration Options

core (Core Configuration)

ParameterTypeDefaultDescription
apiFnFunction-Required, API request function
apiParamsObject{}Default request parameters
excludeParamsArray[]Excluded parameter fields
immediateBooleantrueWhether to load data immediately
columnsFactoryFunction-Column configuration factory function
paginationKeyObject{current: 'current', size: 'size'}Pagination field mapping

transform (Data Processing)

ParameterTypeDefaultDescription
dataTransformerFunction-Data transformation function
responseAdapterFunctiondefaultResponseAdapterResponse data adapter

performance (Performance Optimization)

ParameterTypeDefaultDescription
enableCacheBooleanfalseWhether to enable cache
cacheTimeNumber300000Cache time (milliseconds)
debounceTimeNumber300Debounce delay (milliseconds)
maxCacheSizeNumber50Maximum cache entries

hooks (Lifecycle Hooks)

ParameterTypeDescription
onSuccessFunctionData loading success callback
onErrorFunctionError handling callback
onCacheHitFunctionCache hit callback
resetFormCallbackFunctionReset form callback

Return Values

PropertyTypeDescription
dataRef<T[]>Table data
loadingReadonly<Ref<boolean>>Loading state
errorReadonly<Ref<TableError | null>>Error state
hasDataComputedRef<boolean>Whether has data
isEmptyComputedRef<boolean>Whether data is empty
PropertyTypeDescription
paginationReadonly<Reactive<PaginationParams>>Pagination state
handleSizeChangeFunctionPage size change handler
handleCurrentChangeFunctionCurrent page change handler
PropertyTypeDescription
searchParamsReactive<P>Search parameters
resetSearchParamsFunctionReset search parameters

Data Operations

MethodDescription
fetchDataManually load data, use with immediate option
getDataGet data (reset to first page)
getDataDebouncedGet data (debounced)
clearDataClear data

Refresh Strategies

MethodUse CaseDescription
refreshDataManual refreshClear all cache and reload data
refreshSoftScheduled refreshClear only current search condition cache
refreshCreateAfter addingReturn to first page and clear pagination cache
refreshUpdateAfter updatingKeep current page, clear only current search cache
refreshRemoveAfter deletingSmart page handling to avoid empty pages

Cache Control

Property/MethodDescription
cacheInfoCache statistics information
clearCacheClear cache (supports multiple strategies)
clearExpiredCacheClear expired cache

Column Configuration (Optional)

MethodDescription
columnsTable column configuration
columnChecksColumn display control
addColumnAdd column
removeColumnRemove column
toggleColumnToggle column visibility
updateColumnUpdate column configuration
resetColumnsReset column configuration

Usage Scenarios

1. Basic Table

Suitable for simple data display scenarios:

typescript
const { data, loading, pagination } = useTable({
  core: {
    apiFn: fetchGetUserList,
    columnsFactory: () => basicColumns,
  },
});

2. Search Table

Table with search functionality:

typescript
const { searchParams, getData, resetSearchParams } = useTable({
  core: {
    apiFn: fetchGetUserList,
    apiParams: { name: "", status: "" },
  },
  performance: {
    debounceTime: 500, // Search debounce
  },
});

// Search
const handleSearch = () => {
  Object.assign(searchParams, formData);
  getData();
};

3. High-Performance Table

High-performance table with caching enabled:

typescript
const { cacheInfo, clearCache } = useTable({
  core: {
    apiFn: fetchGetUserList,
  },
  performance: {
    enableCache: true,
    cacheTime: 10 * 60 * 1000, // 10 minutes cache
    maxCacheSize: 200,
  },
  hooks: {
    onCacheHit: (data) => {
      console.log("Data retrieved from cache:", data.length);
    },
  },
});

4. CRUD Table

Complete Create, Read, Update, Delete table:

typescript
const { refreshCreate, refreshUpdate, refreshRemove } = useTable({
  core: {
    apiFn: fetchGetUserList,
  },
});

// After adding user
const handleAddUser = async () => {
  await addUser(userData);
  refreshCreate(); // Return to first page
};

// After editing user
const handleEditUser = async () => {
  await updateUser(userData);
  refreshUpdate(); // Keep current page
};

// After deleting user
const handleDeleteUser = async () => {
  await deleteUser(userId);
  refreshRemove(); // Smart page handling
};

Advanced Features

Cache Strategies

useTable provides four cache invalidation strategies:

typescript
import { CacheInvalidationStrategy } from "@/composables/useTable";

// Clear all cache
clearCache(CacheInvalidationStrategy.CLEAR_ALL, "Manual refresh");

// Clear only current search condition cache
clearCache(CacheInvalidationStrategy.CLEAR_CURRENT, "Search data");

// Clear pagination related cache
clearCache(CacheInvalidationStrategy.CLEAR_PAGINATION, "Add data");

// Keep all cache
clearCache(CacheInvalidationStrategy.KEEP_ALL, "Keep cache");

Custom Response Adapter

Handle different backend response formats:

typescript
const { data } = useTable({
  core: {
    apiFn: fetchGetUserList,
  },
  transform: {
    responseAdapter: (response) => {
      // Adapt custom response format
      return {
        records: response.list,
        total: response.totalCount,
        current: response.pageNum,
        size: response.pageSize,
      };
    },
  },
});

Data Transformation

Transform the retrieved data:

typescript
const { data } = useTable({
  core: {
    apiFn: fetchGetUserList,
  },
  transform: {
    dataTransformer: (records) => {
      return records.map((item) => ({
        ...item,
        fullName: `${item.firstName} ${item.lastName}`,
        statusText: item.status === 1 ? "Active" : "Inactive",
      }));
    },
  },
});

Dynamic Column Configuration

Dynamically manage table columns at runtime:

typescript
const { addColumn, removeColumn, toggleColumn, updateColumn } = useTable({
  core: {
    apiFn: fetchGetUserList,
    columnsFactory: () => initialColumns,
  },
});

// Add column
addColumn({
  prop: "remark",
  label: "Remark",
  width: 150,
});

// Remove column
removeColumn("status");

// Toggle column visibility
toggleColumn("phone");

// Update column configuration
updateColumn("name", {
  label: "User Name",
  width: 200,
});

Error Handling

useTable has built-in comprehensive error handling mechanisms:

typescript
const { error } = useTable({
  core: {
    apiFn: fetchGetUserList,
  },
  hooks: {
    onError: (error) => {
      // Custom error handling
      if (error.code === "NETWORK_ERROR") {
        ElMessage.error("Network connection failed, please check your network");
      } else {
        ElMessage.error(error.message);
      }
    },
  },
});

// Display error in template
// <div v-if="error" class="error">{{ error.message }}</div>

Debugging Features

Enable debug mode to view detailed logs:

typescript
const { cacheInfo } = useTable({
  core: {
    apiFn: fetchGetUserList,
  },
  debug: {
    enableLog: true,
    logLevel: "info",
  },
});

// View cache statistics
console.log("Cache info:", cacheInfo.value);

Best Practices

1. Proper Cache Usage

typescript
// ✅ Recommended: Enable cache for frequently accessed data
const { data } = useTable({
  performance: {
    enableCache: true,
    cacheTime: 5 * 60 * 1000, // 5 minutes
  },
});

// ❌ Not recommended: Enable cache for real-time data

2. Choose Appropriate Refresh Strategies

typescript
// ✅ Use refreshCreate after adding data
const handleAdd = () => {
  refreshCreate(); // Return to first page
};

// ✅ Use refreshUpdate after editing data
const handleEdit = () => {
  refreshUpdate(); // Keep current page
};

// ✅ Use refreshRemove after deleting data
const handleDelete = () => {
  refreshRemove(); // Smart page handling
};

3. Optimize Search Experience

typescript
// ✅ Use debounced search
const { getDataDebounced } = useTable({
  performance: {
    debounceTime: 300,
  },
});

const handleSearch = () => {
  getDataDebounced(); // Auto debounce
};

4. Error Handling

typescript
// ✅ Provide friendly error messages
const { error } = useTable({
  hooks: {
    onError: (error) => {
      ElMessage.error(error.message || "Data loading failed");
    },
  },
});

Examples

useTable Examples

Released under the MIT License