一、Free-Table組件分析
<free-table
? v-show="showTable"
? v-model:page="params.pageNum"? ? ?雙向綁定當前頁大小,支持動態更新
? v-model:limit="params.pageSize"? ? ?雙向綁定每頁大小,支持動態更新
? v-loading="tableLoading"? ??顯示加載動畫
? :data="tableList"? ? ?綁定表格數據
? :column="realTableColumn"? ??定義表格列的配置
? :total="total"? ??數據總條數,用于計算分頁頁數
? :page-size="params.pageSize"? ??每頁顯示的條數
? :height="tableHeight"? ??設置表格高度(需自定義數值)
? :header-cell-style="{ background: '#F9F9FA' }"? ?自定義表頭單元格的樣式。
? :class="densityClass"? ?動態綁定表格樣式類,支持表格密度切換
? pagination? ??啟用分頁功能
? border? ?啟用表格邊框
? stripe? ??啟用斑馬紋樣式
? @pagination="getTableList"? ??分頁控件觸發時調用的方法,通常用于重新加載數據
/>
二、組件初始化階段
1、初始化響應式狀態對象:tablebody。
2、核心狀態:
-
表格高度 ( tableHeight )
-
數據加載狀態 ( tableLoading )
-
表格數據 ( tableList )
-
總條數 ( total )
-
分頁參數 ( params ):設置默認分頁參數。(第1頁,每頁50條)
const tableBody = reactive<stateType>({tableHeight: 600,showTable: true,tableLoading: false,tableList: [],total: 0,params: {pageNum: 1,pageSize: 50, // 默認每頁50條},
});
三、表單和表格配置
1、表單字段:
通過 getFormFields 獲取表單配置:
const formDataModel = reactive({});const formData = computed(() => ({showButtons: false,confirmText: '查詢',model: formDataModel, // 綁定表單數據模型fields: getFormFields(), // 獲取表單字段配置
}));
getFormFields() 返回的表單配置:
[{ prop: 'dw', type: 'input', placeholder: '單位' },{ prop: 'yd', type: 'datePicker', placeholder: '月度' }
]
2、表格列:
通過 getTableColumn 獲取表格列配置:
const tableColumn = getTableColumn();
四、組件掛載自動加載數據
onMounted(init); // 組件掛載時觸發數據加載
const init = () => {getTableList();
};
五、核心數據獲取方法
const getTableList = async () => {try {tableBody.tableLoading = true;// 合并分頁參數和表單參數const params = {...tableBody.params,...formDataModel};const res: any = await getInfoApi(params);if (res.status === 200) {tableBody.tableList = res.data.records || [];tableBody.total = res.data.total ? Number(res.data.total) : 0;} else {ElMessage.warning(res.message);}} finally {tableBody.tableLoading = false;}
};
注:其中 res.status 的 status 為狀態名,
不同接口可能會有不同的狀態名(如code等),所以需要根據不同情況進行修改?。
1、參數合并策略
const params = {...tableBody.params, // 分頁參數 { pageNum: 1, pageSize: 50 }...formDataModel // 表單參數 { dw: '單位A', yd: ['2023-01', '2023-06'] }
};
合并后的請求參數示例:
{"pageNum": 1,"pageSize": 50,"dw": "單位A","yd": ["2023-01", "2023-06"]
}
2、多種解構方式?
功能/解構方式 | 直接解構:data.rows | 對象訪問:res.data.rows |
API調用 | const { data, code, message } = await pageApi(params); | const res: any = await getInfoApi(params); |
狀態碼檢查 | if (code === 200)? | if (res.status === 200)? |
數據賦值 | tableBody.tableList = data.rows; | tableBody.tableList = res.data.records; |
3、響應數據處理
1.直接賦值
特點:保持原始結構 + 分頁信息。
其中records要與接口返回的數組名一致。
如若是"list": [...],那么就得是res.data.list。
tableBody.tableList = res.data.records || []; // 表格數據
tableBody.total = Number(res.data.total) || 0; // 總數
假設后端返回數據結構:?
{"status": 200,"data": {"records": [...], // 當前頁數據"total": 1250 // 總記錄數}
}
2.字段映射
特點:必須轉換 + 空安全
orgTypeList.value = (data as OrgItem[]).map(item => ({label: item.name,value: item.id,
?轉換過程:
// 原始數據
[{ name: "米哈油", id: "org-001" }]
// 轉換后(丟棄id,保留label/value)
[{ label: "米哈油", value: "org-001" }]
為什么一定要轉換為 { label, value } 格式?
- 適配 UI 組件的數據格式
- 統一處理邏輯
- 減少不必要的數據處理
- 清晰分離顯示值與存儲值
在少數簡單場景下可以直接使用原始數據:
- 純字符串/數字的簡單列表
- 組件明確支持自定義字段映射
六、用戶交互觸發點
1、查詢按鈕
const submitHandler = () => {console.log('Form Data Model:', formDataModel);init(); // 觸發數據加載
};
2、數據統計按鈕
const dataStatistics = () => {init(); // 同樣觸發數據加載
};
3、表格刷新/分頁
注:該代碼所在文件位置:index.vue。
<!-- Template中 -->
<table-operate @on-refresh="getTableList"/>
<free-table @pagination="getTableList"/>
七、動態列顯示?
按需求選擇哪些列顯示,哪些列不顯示。
1. 表格操作組件引用index
<table-operate ref="tableOperateRef" :table-column="tableColumn"@on-refresh="getTableList">
</table-operate>
2. 動態列計算屬性hooks
const realTableColumn = computed(() => tableOperateRef.value?.realTableColumn ?? []
);
3. 表格組件綁定index
<free-table :column="realTableColumn"></free-table>