最近項目需求:在表格底部添加一行爲金額的合計行,然後分頁每頁都顯示,金額字段是後端返回的數據,前端不進行計算。
因爲項目的UI框架使用的是Ant Design,找了一下Table的使用方法,發現居然沒有合計數據這樣一個功能,但是提供了一個footer屬性用來做Table底部的空間顯示。然後我使用footer中添加一個Table來做了一下合計行顯示,勉強能做出來,但是需要修改Table的css樣式,並且在不同分辨率下表格的線框無法對齊,總之就是很low。
多方查找資料,以及自己的不斷試錯,終於找到了一種頗爲完美的解決方法:將合計行追加到table表格內部,修改分頁功能,維護也更加方便。
先上圖,切換分頁後table底部也有合計行:
上代碼:
import React, { PureComponent } from 'react';
import { Table } from 'antd';
import { formatMoney } from '@/utils/utils'; //自定義格式化金額方法
// columns中的多餘字段刪除掉了,都是重複的樣式,這裏爲了減少代碼量。
const columns = [
{
title: '序號',
width: 66,
dataIndex: 'totalIndex',
render: (text, record, index) => {
if (record.totalIndex == '合計') {
return text;
} else {
return ++index; //++index相當於index+1
}
}
},
{
title: '憑證號',
width: 200,
dataIndex: 'voucherCode',
render: (text, record) => {
//因爲只有合計行追加了字段totalIndex,所以判斷當前字段來讓合計行的憑證號列數據爲空,只計算金額列。
//產品說讓空白顯示!!!
if (record.totalIndex) {
return '';
} else {
return text || '--';
}
}
},
{
title: '借方金額',
dataIndex: 'debit',
render: text => formatMoney(text)
},
{
title: '貸方金額',
dataIndex: 'credit',
render: text => formatMoney(text)
}
];
export default class ListTable extends PureComponent {
// 切換分頁時調用函數
changePagination = pagination => {
const {
dispatch,
queryFinanceList: { formValues }
} = this.props;
const params = {
page: pagination.current, //當前分頁的頁碼
limit: pagination.pageSize - 1, //這裏必須要減1,因爲與後臺規定每頁獲取的數據爲10,此處的pageSize爲11。
queryCondition: { ...formValues },
};
dispatch({
type: 'queryFinanceList/fetch',
payload: params,
});
};
render() {
const {
loading,
queryFinanceList: {
list,
pageNum,
total: computedTotal, //重命名爲computedTotal
pages,
pageSize
},
} = this.props;
//定義合計行數據
const totalRow = {
id: String(Math.random()),
totalIndex: '合計',
debit: 1165000, //應當取從後臺返回數據,此處爲演示,所以自定義了默認值
credit: 1183000, //應當取從後臺返回數據,此處爲演示,所以自定義了默認值
}
//將合計行數據添加到list數組中後生成新數組:_list,此時table每頁的數據爲11
const _list = list && list.length > 0 ? [...list, totalRow] : [];
//table與pagination組件之間的聯動
//因爲table表格每頁顯示的數據被pagenation分頁默認的每頁顯示數pageSize所限制,默認爲10,爲了讓合計行顯示到頁面上,需+1。
const _pageSize = pageSize + 1;
//table表格需要獲取的總數據,爲了讓table將後臺獲取數據和新增合計行數據全部顯示出來,需重新計算總數。
const _total = computedTotal + pages;
//分頁設置
const paginationDefault = {
showSizeChanger: true,
showQuickJumper: true,
current: pageNum,
total: _total,
pageSize: _pageSize,
//因爲與後臺規定每頁獲取的數據爲10,而前端自定義追加了一條合計行,這導致當前table的每頁數據爲11條,所以需要手動將分頁數據+1
//若是想顯示爲['10', '20', '30', '40'],則修改每頁獲取數據爲9即可。
pageSizeOptions: ['11', '21', '31', '41'],
//此處顯示的是從後臺獲取的總數據數,合計行不在其中。
showTotal: () => `共${computedTotal}條記錄`
}
return (
<Table
loading={loading}
rowKey={'id'}
scroll={{ x: true }}
bordered={true}
loading={loading}
columns={columns}
dataSource={_list}
pagination={paginationDefault}
onChange={this.changePagination}
/>
);
}
}
如果使用過ant design的Table組件以及Pagination組件的話,上面基本沒有什麼難點。
邏輯理解的話有兩個難點:
1、分頁功能的total和pageSize的計算方式?
2、合計行totalRow與後臺返回數據的關係?
在table表格中使用pagination分頁功能後,table每頁顯示的數據被pagination的pageSize(每頁顯示數據)限制,如果pageSize爲10的話,那table中每頁就只能顯示10條數據。現在我們手動給table添加了合計行totalRow,那table每頁的數據顯示就變爲了11,這時候pageSize若還是10,那第11條數據是顯示不出來的,所以pageSize需要修改爲11,這樣合計行totalRow就能顯示出來了。我們在切換分頁的時候,是需要請求後臺數據的,pageSize需要當做請求參數傳送給後臺。但是這時候我們設定了pageSize爲11,而規定的每頁顯示的真實數據爲10,所以需要在請求數據時pageSize-1。
total也需要跟隨pageSize的+1而改變。如果後臺返回的total爲61,pageSize爲10,pages(幾個頁面)爲7,那麼“新total”的計算方式爲:61+1*7=68。因爲在table每頁中都添加了一條合計行totalRow的數據,所以計算方式爲61+1*7=68。如果手動添加了兩條數據,那麼總數計算就應當爲:61+2*7=75。
若還有更優美的實現方式,歡迎留言分享。