一、建立通用型表格的需求
實現一個通用型表格元件,具備以下功能:
- 動態列配置。
- 分頁功能。
- 排序功能。
- 可擴充套件的行操作功能。
二、設計通用型表格元件
首先,需要設計一個基礎的表格元件,它接受列配置、資料和分頁資訊等引數。
1. 建立 useTable
Hook
在 src/hooks
目錄下建立 useTable.js
檔案:
import { ref, reactive, onMounted, toRefs } from 'vue'; export function useTable(fetchData) { const state = reactive({ loading: false, data: [], pagination: { currentPage: 1, pageSize: 10, total: 0, }, sort: { field: '', order: '', }, }); const loadData = async () => { state.loading = true; const { currentPage, pageSize } = state.pagination; const { field, order } = state.sort; const result = await fetchData(currentPage, pageSize, field, order); state.data = result.data; state.pagination.total = result.total; state.loading = false; }; const changePage = (page) => { state.pagination.currentPage = page; loadData(); }; const changePageSize = (size) => { state.pagination.pageSize = size; loadData(); }; const changeSort = (field, order) => { state.sort.field = field; state.sort.order = order; loadData(); }; onMounted(() => { loadData(); }); return { ...toRefs(state), loadData, changePage, changePageSize, changeSort, }; }
2. 建立 TableComponent.vue
在 src/components
目錄下建立 TableComponent.vue
檔案:
<template> <div> <table> <thead> <tr> <th v-for="col in columns" :key="col.key" @click="changeSort(col.key)"> {{ col.title }} <span v-if="sort.field === col.key">{{ sort.order === 'asc' ? '↑' : '↓' }}</span> </th> </tr> </thead> <tbody> <tr v-for="row in data" :key="row.id"> <td v-for="col in columns" :key="col.key">{{ row[col.key] }}</td> </tr> </tbody> </table> <div class="pagination"> <button @click="changePage(pagination.currentPage - 1)" :disabled="pagination.currentPage === 1">Previous</button> <span>{{ pagination.currentPage }} / {{ Math.ceil(pagination.total / pagination.pageSize) }}</span> <button @click="changePage(pagination.currentPage + 1)" :disabled="pagination.currentPage === Math.ceil(pagination.total / pagination.pageSize)">Next</button> </div> </div> </template> <script> import { ref, onMounted } from 'vue'; import { useTable } from '@/hooks/useTable'; export default { props: { fetchData: { type: Function, required: true, }, columns: { type: Array, required: true, }, }, setup(props) { const { data, loading, pagination, sort, loadData, changePage, changePageSize, changeSort } = useTable(props.fetchData); return { data, loading, pagination, sort, loadData, changePage, changePageSize, changeSort, }; }, }; </script> <style scoped> .pagination { display: flex; justify-content: center; margin-top: 10px; } </style>
三、使用通用型表格元件
在實際專案中,可以這樣使用這個通用型表格元件:
1. 建立 ExampleTable.vue
元件
在 src/views
目錄下建立 ExampleTable.vue
檔案:
<template> <div> <TableComponent :fetchData="fetchData" :columns="columns" /> </div> </template> <script> import TableComponent from '@/components/TableComponent.vue'; export default { components: { TableComponent, }, setup() { const columns = [ { key: 'name', title: 'Name' }, { key: 'age', title: 'Age' }, { key: 'email', title: 'Email' }, ]; const fetchData = async (page, pageSize, sortField, sortOrder) => { // 模擬資料獲取 const total = 100; const data = Array.from({ length: pageSize }, (v, i) => ({ id: (page - 1) * pageSize + i + 1, name: `Name ${(page - 1) * pageSize + i + 1}`, age: 20 + ((page - 1) * pageSize + i + 1) % 30, email: `user${(page - 1) * pageSize + i + 1}@example.com`, })); return { data, total }; }; return { columns, fetchData, }; }, }; </script>
四、解釋程式碼
-
定義
useTable
Hook:- 使用 Vue 的
ref
和reactive
定義表格狀態。 - 定義
loadData
、changePage
、changePageSize
和changeSort
函式來處理資料載入和分頁、排序變化。 - 使用
onMounted
生命週期鉤子在元件掛載時載入資料。
- 使用 Vue 的
-
定義
TableComponent
元件:- 接受
fetchData
和columns
作為元件屬性。 - 使用
useTable
Hook 獲取表格資料和操作函式。 - 渲染表格頭部、主體和分頁元件,並繫結相關事件。
- 接受
-
使用通用型表格元件:
- 在
ExampleTable.vue
中定義列配置和資料獲取函式。 - 使用
TableComponent
並傳遞fetchData
和columns
屬性。
- 在