阿里出品的Ant Design UI組件用起來(lái)可以說(shuō)是很順手的,但是用多了會(huì)發(fā)現(xiàn)有時(shí)候還能更高效一點(diǎn),那么我就萌生了對(duì)個(gè)別組件驚醒二次封裝的念頭启盛,接下來(lái)我就介紹下我二次封裝的表格組件霜第,事先說(shuō)明:以下組件是基于antdV3版本的葛家,V4版本使用分頁(yè)會(huì)存在問(wèn)題(已解決待下次更新)
詳細(xì)說(shuō)明見git倉(cāng)庫(kù) --->二次封裝代碼傳送門
如果登不上可以去gitee=》二次封裝代碼傳送門
有積分得也可以直接在csdn下載(謝謝各位老板)=》二次封裝代碼壓縮包
下面我將分模塊的介紹下我的封裝思路及各個(gè)部門的功能
參數(shù)說(shuō)明
TableComponent.propTypes = { //.propTypes是react規(guī)定的名稱,不可以修改
tableData: PropTypes.shape({
url: PropTypes.string.isRequired, // 路徑類型
rowSelection: PropTypes.bool, // 復(fù)選標(biāo)識(shí)
lineIndex: PropTypes.bool, // 序號(hào)標(biāo)識(shí)
columns: PropTypes.array.isRequired, // 列參數(shù)
dataToOut: PropTypes.bool, // 數(shù)據(jù)外傳標(biāo)識(shí)
addParams: PropTypes.object, // 新增參數(shù)
size: PropTypes.oneOf(['default', 'middle', 'small']), // 表格尺寸
handleOverflow: PropTypes.bool, // 全局溢出處理,不需要再單獨(dú)每個(gè)列設(shè)置(設(shè)置后忽略單獨(dú)設(shè)置)
falseData: PropTypes.array, // 假數(shù)據(jù)
method: PropTypes.oneOf(['get', 'post']), // 請(qǐng)求方式
changePageParam:PropTypes.objectOf(function(propValue, key, componentName, location, propFullName) {
let allowKeys = [ 'pageSize', 'page', 'totalCount', 'list' ]
if (allowKeys.indexOf(key) < 0 ) {
return new Error(
'Invalid prop `' + componentName + '` supplied to' +
' `' + propFullName + '`. Validation failed.'
);
}
}), // 替代頁(yè)面參數(shù)
scroll: PropTypes.object, // 滾動(dòng)配置
}),
// 列新參數(shù)說(shuō)明(由于不知道怎么設(shè)置tableData.columns的參數(shù)類型泌类,
// 所以暫放在這癞谒,但組件沒(méi)有這個(gè)參數(shù))
Columns: PropTypes.shape({
overflow: PropTypes.bool, // 列移除處理(移除顯示省略號(hào)...)
})
};
基礎(chǔ)顯示
基礎(chǔ)列表顯示功能只需要一個(gè)地址參數(shù)url和列參數(shù)columns就可以實(shí)現(xiàn)列表的顯示,當(dāng)然刃榨,前提是你請(qǐng)求參數(shù)為
pageData: {
[pageSize]: 10, // 變量屬性名弹砚,ES6標(biāo)準(zhǔn),實(shí)現(xiàn)自定義請(qǐng)求體,兼容不同的后端請(qǐng)求體實(shí)體類
[page]: 1,
},
并且沒(méi)有其他的篩選參數(shù)枢希,這樣通過(guò)getData方法就是獲取列表參數(shù)桌吃。getData()如下:
/**
* 獲取表格數(shù)據(jù)
* @param p 參數(shù)
*/
getData(p) {
let _this = this.props.tableData;
// 請(qǐng)求方式再設(shè)置(tabs切換時(shí)不會(huì)刷新標(biāo)簽頁(yè)內(nèi)容,所以需要重置請(qǐng)求體
// 否則兩個(gè)標(biāo)簽頁(yè)請(qǐng)求體不同時(shí)點(diǎn)擊切換標(biāo)簽頁(yè)并跳轉(zhuǎn)頁(yè)會(huì)報(bào)405錯(cuò)誤)
setMethod(_this);
// 參數(shù)再設(shè)置(同個(gè)頁(yè)面兩個(gè)table相互切換時(shí)苞轿,tableData會(huì)更新轉(zhuǎn)換茅诱,
// 但是自定義參數(shù)不會(huì)轉(zhuǎn)換为流,需要手動(dòng)判斷)
if (_this.changePageParam && Object.keys(_this.changePageParam).length > 0) {
this.newParam(_this.changePageParam);
}
if (_this.url) {
// 篩選換頁(yè)加載中樣式
this.setState({
loading: true
});
// 獲取表格顯示數(shù)據(jù)
api[_method](_this.url, p).then(res => {
res = this.traverse(res); // 污染原始數(shù)據(jù)
if (res[list].length > 0) {
// 表格數(shù)據(jù)添加key值
let index;
for (const key in res[list]) {
if (res[list].hasOwnProperty(key)) {
index = p[pageSize]*(p[page] - 1) + Number(key)
res[list][key]['onlyKey'] = index;
}
}
this.setState({
pagination: {
...this.state.pagination,
total: res[totalCount],
},
loading: false, // 關(guān)閉加載中
})
if (_this.dataToOut) {
this.props.getTableDatas(res); // 表格數(shù)據(jù)外送處理
} else {
this.setState({
data: res[list],
})
}
} else {
// message.warn('獲取列表信息為空!')
if (_this.dataToOut) this.props.getTableDatas(res); // 表格數(shù)據(jù)外送處理
this.setState({
loading: false,
data: [],
pagination: {
...this.state.pagination,
total: res[totalCount],
},
})
}
}).catch(err => {
if (_this.dataToOut) this.props.getTableDatas(); // 表格數(shù)據(jù)外送處理
this.setState({
loading: false,
data: [],
pagination: {
...this.state.pagination,
total: 0,
},
})
// message.error('獲取信息失斎貌尽敬察!')
log('err: '+ err);
})
} else {
// message.error('接口路徑不得為空!')
log('接口路徑不得為空!')
this.setState({
loading: false
})
}
}
切記:在外送數(shù)據(jù)處理后一定要調(diào)用inputData ()傳入數(shù)據(jù),否則表格將不顯示尔当。
自定義請(qǐng)求體返回體
在getData()方法里的備注里已經(jīng)有簡(jiǎn)單的提到了莲祸,接下來(lái)詳細(xì)說(shuō)明下。主要是通過(guò)參數(shù)changePageParam實(shí)現(xiàn)椭迎,使用方法詳見源代碼md文件锐帜,實(shí)現(xiàn)方法看下es6變量屬性名和組件里的traverse()方法
changePageParam: {page:'pageNo',totalCount:'total',pagesize:'xxx',list: 'list'},
組件里有四個(gè)對(duì)外的參數(shù),也就是列表必須的四個(gè)參數(shù):頁(yè)數(shù)page畜号,頁(yè)條數(shù)pagesize缴阎,返回列表屬性名:list返回總條數(shù)屬性名:totalCount。有了這四個(gè)參數(shù)基本的顯示肯定是沒(méi)問(wèn)題的简软,再根據(jù)你們定義的參數(shù)名對(duì)應(yīng)進(jìn)行修改就可自定義請(qǐng)求體返回體蛮拔。這樣是達(dá)到了自定義請(qǐng)求體返回體的效果,但同時(shí)也埋了個(gè)雷痹升,就是頁(yè)面使用多個(gè)表格組件時(shí)參數(shù)不一樣的話分頁(yè)/請(qǐng)求會(huì)出問(wèn)題建炫,還沒(méi)想到好的解決辦法。疼蛾。肛跌。
篩選功能
通過(guò)調(diào)用inputParam()方法實(shí)現(xiàn),代碼如下:
/**
* 傳入新參數(shù)進(jìn)行篩選
* @param p 新參數(shù)(為空表示重置)
*/
inputParam(p = {}) {
let param = {};
if (Object.keys(p).length === 0) {
param = {
...this.state.addParam, // 全局字段
[pageSize]: this.state.pageData[pageSize],
[page]: 1, // 頁(yè)碼
}
// 將新增參數(shù)寫入state,避免分頁(yè)報(bào)錯(cuò)
this.setState({
pageData: {
...param
},
pagination: {
...this.state.pagination,
current: 1
},
screenParam: {},
})
} else {
param = {
...this.state.pageData,
[page]: 1, // 頁(yè)碼
...this.state.addParam, // 全局字段
...p,
}
// 將新增參數(shù)寫入state,避免分頁(yè)報(bào)錯(cuò)
this.setState({
pageData: {
...this.state.pageData,
[page]: 1, // 頁(yè)碼
},
pagination: {
...this.state.pagination,
current: 1
},
screenParam: p,
})
}
this.getData(param);
}
使用詳見源代碼md文件方法說(shuō)明察郁。
多選實(shí)現(xiàn)和??選實(shí)現(xiàn):
多選實(shí)現(xiàn)就是沿用antd的方法設(shè)置rowSelection:true
禁選的設(shè)置通過(guò)調(diào)用setUnselect(param, key, type)方法衍慎,代碼如下:
/**
* 多選后不可選設(shè)置
* @param key 判斷值
*/
setCheckboxProps (key){
// 判斷多選啟用
if (this.props.tableData.rowSelection) {
this.setState({
checkboxPropsKey: key
})
this.getCheckboxProps(null, key)
}
}
/**
* 表格不可選條目設(shè)置
* @param param 字段
* @param key 不可選判斷
* @param type 判斷類型(true:record[unselectPar] === unselect是不可選,false:record[unselectPar] !== unselect是不可選)
*/
setUnselect(param, key, type=undefined){
unselectPar = param;
this.setState({unselect: key})
if (type === false) {
this.setState({unselectType: false})
} else {
this.setState({unselectType: true})
}
this.getCheckboxProps(null, undefined, key)
}
// 多選回調(diào)函數(shù)
onSelectChange = (selectedRowKeys, selectedRows) => {
// console.log(selectedRowKeys);
if (selectedRows.length === 0) {
this.setState({checkboxPropsKey: undefined})
}
this.setState({ selectedRowKeys });
this.props.getSelectData(selectedRows);
};
/**
* 多選設(shè)置
* @param record 列表
* @param key 選擇后不可選key值
* @param unselect 列表不可選設(shè)置
*/
getCheckboxProps = (record, key=undefined, unselect=undefined) => {
if (record !== null && key !== undefined) {
return({
disabled: record.onlyKey !== key, // Column configuration not to be checked
})
}
if (record !== null && key === undefined && unselect !== undefined) {
if (this.state.unselectType) {
return({
disabled: record[unselectPar] === unselect, // 相等時(shí)不可選
})
} else {
return({
disabled: record[unselectPar] !== unselect, // 不等時(shí)不可選
})
}
}
};
使用詳見源代碼md文件方法說(shuō)明
表格刷新
又是外部需要手動(dòng)刷新表格內(nèi)容皮钠,就可以調(diào)用refresh()方法稳捆,代碼如下:
/**
* 表格刷新
*/
refresh() {
const { addParam, screenParam, pageData } = this.state
const param = {
...addParam,
...screenParam,
...pageData
}
this.getData(param)
this.setState({ selectedRowKeys: [] }) // 多選清空
}
使用詳見源代碼md方法說(shuō)明
清除多選
有時(shí)不想刷新表格只想清楚多選,可以調(diào)用cleanSelectedRow()方法鳞芙,代碼如下:
// 清除多選
cleanSelectedRow(){
this.setState({selectedRowKeys: []}) // 多選清空
}
使用詳見源代碼md文件方法說(shuō)明
單元格超長(zhǎng)溢出處理
單獨(dú)列的溢出處理可以使用columns參數(shù)里的overflow搭配width設(shè)置寬度眷柔,超過(guò)顯示省略號(hào)期虾。
全部設(shè)置的話使用handleOverflow參數(shù)原朝,這樣搭配列參數(shù)的width設(shè)置寬度,超過(guò)顯示省略號(hào)镶苞,就不用挨個(gè)列的設(shè)置overflow了喳坠。當(dāng)然也可以使用antd自帶的ellipsis屬性,待筆者有空完善下茂蚓。壕鹉。剃幌。
注意: 如果你的列參數(shù)設(shè)置了 render = (text) =>{} 方法這樣溢出處理就失效了,只能超過(guò)換行晾浴。具體原因詳見源碼componentWillMount ... // 生命周期添加內(nèi)容溢出處理负乡,當(dāng)然也是能解決的,但是筆者懶得去動(dòng)了脊凰,用的地方不多抖棘,等需求多了我在兼容處理下。
其他功能
還有比如排序狸涌,假數(shù)據(jù)顯示切省,請(qǐng)求體修改這幾個(gè)功能也都是支持的,具體使用詳見源代碼md文件方法說(shuō)明
已知bug
同頁(yè)面存在多個(gè)表格組件時(shí)會(huì)存在串參數(shù)的問(wèn)題帕胆,導(dǎo)致請(qǐng)求出錯(cuò)朝捆、分頁(yè)出錯(cuò)、排序顯示NaN問(wèn)題懒豹。
不足之處
-
無(wú)法實(shí)現(xiàn)內(nèi)置行編輯
由于V3版本表達(dá)的在封裝芙盘,如果加上行編輯那么之前版本的refs都不能用了,代價(jià)太大脸秽,使用率也低所以放棄何陆。 -
分頁(yè)處理
分頁(yè)處理的代碼其實(shí)可以優(yōu)化下的,不需要那么復(fù)雜豹储,可以使用組件自帶onChange方法更簡(jiǎn)潔的實(shí)現(xiàn)贷盲。 -
還有很多...
最后希望各位讀者能夠賞臉試用下我的組件,或者給我提出其他修改優(yōu)化的寶貴意見剥扣,筆者再這先謝謝大家了巩剖。 有問(wèn)題或者發(fā)現(xiàn)bug或者有新需求都可以在git上留言或者直接這下面留言,筆者一定第一時(shí)間解決钠怯,謝謝各位大哥賞臉試用佳魔,謝謝謝謝!;薮丁>舷省!断国!
二次封裝源碼
import React, { Component } from 'react';
import { Table, message, Tooltip } from 'antd';
import PropTypes from 'prop-types';
import './index.less'
import api from './network'
let { log, error } = console;
let page = 'page'; // 頁(yè)碼變量
let pageSize = 'pageSize'; // 頁(yè)條數(shù)
let totalCount = 'totalCount'; // 總條數(shù)
let unselectPar = undefined; // 不可選判斷字段
let list = 'list'; // 列表
let _method = 'post'; // 請(qǐng)求方式
// 公共方法
// 設(shè)置請(qǐng)求體
function setMethod(params) {
let _this = params;
// 請(qǐng)求方式
try {
if (_this.method === 'post' || _this.method === 'get') {
_method = _this.method;
} else if (_this.method === undefined || _this.method === null) {
_method = 'post';
} else{
throw new Error('Request method `'+_this.method + '` is not allowed')
}
} catch (err) {
error(err);
}
}
class TableComponent extends Component {
constructor(props) {
super(props)
// 全局變量重置默認(rèn)值
page = 'page'; // 頁(yè)碼變量
pageSize = 'pageSize'; // 頁(yè)條數(shù)
totalCount = 'totalCount'; // 總條數(shù)
unselectPar = undefined; // 不可選判斷字段
list = 'list'; // 列表
_method = 'post'; // 請(qǐng)求方式
let _this = this.props.tableData;
// 請(qǐng)求方式
setMethod(_this);
// 判斷是否使用新頁(yè)面參數(shù)
if (_this.changePageParam && Object.keys(_this.changePageParam).length > 0) {
this.newParam(_this.changePageParam);
}
this.state = {
data: [],
pageData: {
[pageSize]: 10,
[page]: 1,
},
// 分頁(yè)參數(shù)
pagination: {
position: 'bottom',
total: 0,
showTotal: total => `共計(jì) ${total} 條`,
pageSize: 10,
pageSizeOptions: ['10', '20', '50', '100'],
showSizeChanger: true,
// 頁(yè)碼贤姆、條數(shù)變化回調(diào)
onShowSizeChange: this.pageSizeChange,
onChange: this.pageChange,
current: 1
},
// 加載中
loading: true,
size: 'default',
columns: [], // 列數(shù)據(jù)
addParam: {}, // 全局參數(shù)字段存放
screenParam: {}, // 篩選參數(shù)字段存放
selectedRowKeys: [], // Check here to configure the default column
checkboxPropsKey: undefined, // 多選比較值
unselect: undefined, // 列表不可選
unselectType: true, // 判斷類型,相等不可選還是不等時(shí)不可選
}
// console.log(this.state.pagination);
}
componentWillMount() {
let _this = this.props.tableData;
// 添加序號(hào)
if (_this.lineIndex) {
const index = {
title: '序號(hào)',
// width: 70,
align: 'center',
render: (text, record, index) => `${index + 1 + (this.state.pageData[page] - 1) * this.state.pageData[pageSize]}`
}
_this.columns.unshift(index); // 數(shù)組頭部插入
}
// 添加內(nèi)容溢出處理
if (_this.handleOverflow) { // 全局溢出處理
for (const key in _this.columns) {
if (_this.columns.hasOwnProperty(key)) {
const element = _this.columns[key];
if (element.width && !element.render) {
_this.columns[key]['onCell'] = () => {
return {
style: {
maxWidth: element.width,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis',
cursor:'pointer'
}
}
}
_this.columns[key]['render'] = (text) => <Tooltip placement="topLeft" title={text}>{text}</Tooltip>
} else if (element.width && element.render){ // 存在render屬性時(shí)不生效
// message.warn('第'+(Number(key)+1)+'列render屬性已經(jīng)存在稳衬!請(qǐng)移除后再設(shè)置溢出處理霞捡。')
}
}
}
} else {
// 不做全局處理,單獨(dú)每一列的溢出處理
for (const key in _this.columns) {
if (_this.columns.hasOwnProperty(key)) {
const element = _this.columns[key];
if (element.width && !element.render && element.overflow) {
_this.columns[key]['onCell'] = () => {
return {
style: {
maxWidth: element.width,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow:'ellipsis',
cursor:'pointer'
}
}
}
_this.columns[key]['render'] = (text) => <Tooltip placement="topLeft" title={text}>{text}</Tooltip>
}
}
}
}
const param = {
...this.state.pageData,
..._this.addParams,
}
this.setState({
pageData: {
...param
},
addParam: _this.addParams, // 儲(chǔ)存新參數(shù)
columns: _this.columns,
size: _this.size,
})
// 尺寸設(shè)置
if (_this.size) this.setState({ size: _this.size });
// 假數(shù)據(jù)使用
if (_this.falseData) {
this.setState({ data: _this.falseData, loading: false });
} else { this.getData(param) }
}
/**
* 自定義請(qǐng)求體薄疚、返回體
* @param _newParam 新參數(shù)
*/
newParam(_newParam){
let arrKeys = Object.keys(_newParam);
arrKeys.map( name =>{
if (name === 'pageSize') { pageSize = _newParam.pageSize; return name; }
if (name === 'page') { page = _newParam.page; return name; }
if (name === 'totalCount') { totalCount = _newParam.totalCount; return name; }
if (name === 'list') { list = _newParam.list; return name; }
return undefined;
})
}
/** ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓----------向外開放方法--------↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
/**
* 接收外部數(shù)據(jù)
* @param data 顯示數(shù)據(jù)
*/
inputData = (data) => {
this.setState({
data
})
}
/**
* 傳入新參數(shù)進(jìn)行篩選
* @param p 新參數(shù)(為空表示重置)
*/
inputParam(p = {}) {
let param = {};
if (Object.keys(p).length === 0) {
param = {
...this.state.addParam, // 全局字段
[pageSize]: this.state.pageData[pageSize],
[page]: 1, // 頁(yè)碼
}
// 將新增參數(shù)寫入state,避免分頁(yè)報(bào)錯(cuò)
this.setState({
pageData: {
...param
},
pagination: {
...this.state.pagination,
current: 1
},
screenParam: {},
})
} else {
param = {
...this.state.pageData,
[page]: 1, // 頁(yè)碼
...this.state.addParam, // 全局字段
...p,
}
// 將新增參數(shù)寫入state,避免分頁(yè)報(bào)錯(cuò)
this.setState({
pageData: {
...this.state.pageData,
[page]: 1, // 頁(yè)碼
},
pagination: {
...this.state.pagination,
current: 1
},
screenParam: p,
})
}
this.getData(param);
}
/**
* 多選后不可選設(shè)置
* @param key 判斷值
*/
setCheckboxProps (key){
// 判斷多選啟用
if (this.props.tableData.rowSelection) {
this.setState({
checkboxPropsKey: key
})
this.getCheckboxProps(null, key)
}
}
/**
* 表格不可選條目設(shè)置
* @param param 字段
* @param key 不可選判斷
* @param type 判斷類型(true:record[unselectPar] === unselect是不可選碧信,false:record[unselectPar] !== unselect是不可選)
*/
setUnselect(param, key, type=undefined){
unselectPar = param;
this.setState({unselect: key})
if (type === false) {
this.setState({unselectType: false})
} else {
this.setState({unselectType: true})
}
this.getCheckboxProps(null, undefined, key)
}
/**
* 表格刷新
*/
refresh() {
const { addParam, screenParam, pageData } = this.state
const param = {
...addParam,
...screenParam,
...pageData
}
this.getData(param)
this.setState({ selectedRowKeys: [] }) // 多選清空
}
// 清除多選
cleanSelectedRow(){
this.setState({selectedRowKeys: []}) // 多選清空
}
/** ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓----------組件內(nèi)部函數(shù)--------↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
/**
* 遞歸操作赊琳,獲取隨機(jī)返回體內(nèi)的列表參數(shù)
* 當(dāng)對(duì)象中存在 list 和 totalCount 是基本可以確定這就是所需要的列表參數(shù)
* 再加以列表長(zhǎng)度判斷,雖然這樣基本能保證列表參數(shù)的唯一星砰碴,但是還有極概率存在出現(xiàn)問(wèn)題
* 長(zhǎng)度判斷擔(dān)心不可靠躏筏,故暫未加上。
*/
traverse(obj) {
if (obj[list] && !isNaN(obj[totalCount])) {
if (this.state.pageData[pageSize] !== obj[list].length) log('列表長(zhǎng)度不等于頁(yè)條數(shù)');
return obj;
} else {
for (let a in obj) {
if (typeof(obj[a]) === 'object') return this.traverse(obj[a]); //遞歸遍歷
}
}
}
/**
* 獲取表格數(shù)據(jù)
* @param p 參數(shù)
*/
getData(p) {
let _this = this.props.tableData;
// 請(qǐng)求方式再設(shè)置(tabs切換時(shí)不會(huì)刷新標(biāo)簽頁(yè)內(nèi)容呈枉,所以需要重置請(qǐng)求體
// 否則兩個(gè)標(biāo)簽頁(yè)請(qǐng)求體不同時(shí)點(diǎn)擊切換標(biāo)簽頁(yè)并跳轉(zhuǎn)頁(yè)會(huì)報(bào)405錯(cuò)誤)
setMethod(_this);
// 參數(shù)再設(shè)置(同個(gè)頁(yè)面兩個(gè)table相互切換時(shí)寸士,tableData會(huì)更新轉(zhuǎn)換,
// 但是自定義參數(shù)不會(huì)轉(zhuǎn)換碴卧,需要手動(dòng)判斷)
if (_this.changePageParam && Object.keys(_this.changePageParam).length > 0) {
this.newParam(_this.changePageParam);
}
if (_this.url) {
// 篩選換頁(yè)加載中樣式
this.setState({
loading: true
});
// 獲取表格顯示數(shù)據(jù)
api[_method](_this.url, p).then(res => {
res = this.traverse(res); // 污染原始數(shù)據(jù)
if (res[list].length > 0) {
// 表格數(shù)據(jù)添加key值
let index;
for (const key in res[list]) {
if (res[list].hasOwnProperty(key)) {
index = p[pageSize]*(p[page] - 1) + Number(key)
res[list][key]['onlyKey'] = index;
}
}
this.setState({
pagination: {
...this.state.pagination,
total: res[totalCount],
},
loading: false, // 關(guān)閉加載中
})
if (_this.dataToOut) {
this.props.getTableDatas(res); // 表格數(shù)據(jù)外送處理
} else {
this.setState({
data: res[list],
})
}
} else {
// message.warn('獲取列表信息為空弱卡!')
if (_this.dataToOut) this.props.getTableDatas(res); // 表格數(shù)據(jù)外送處理
this.setState({
loading: false,
data: [],
pagination: {
...this.state.pagination,
total: res[totalCount],
},
})
}
}).catch(err => {
if (_this.dataToOut) this.props.getTableDatas(); // 表格數(shù)據(jù)外送處理
this.setState({
loading: false,
data: [],
pagination: {
...this.state.pagination,
total: 0,
},
})
// message.error('獲取信息失敗住册!')
log('err: '+ err);
})
} else {
// message.error('接口路徑不得為空!')
log('接口路徑不得為空!')
this.setState({
loading: false
})
}
}
// 頁(yè)碼改變事件
pageChange = (newPage) => {
let pageData = {
[pageSize]: this.state.pageData[pageSize], // 每頁(yè)的記錄數(shù)字
...this.state.addParam,
...this.state.screenParam
}
pageData[[page]] = newPage;
this.setState({
// selectedRowKeys: [], // 清空多選
pageData: {
[page]: newPage,
[pageSize]: this.state.pageData[pageSize],
},
pagination: {
current: newPage, // 當(dāng)前頁(yè)高亮
}
})
this.getData(pageData);
};
// 頁(yè)顯示條數(shù)改變事件
pageSizeChange = (e, newPageSize) => {
this.setState({
pageData: {
[page]: 1,
[pageSize]: newPageSize
},
pagination: {
...this.state.pagination,
pageSize: newPageSize,
current: 1
}
})
const pageData = {
[pageSize]: newPageSize, // 每頁(yè)的記錄數(shù)字
[page]: 1, // 頁(yè)碼
...this.state.addParam,
...this.state.screenParam
}
this.getData(pageData);
};
// 多選回調(diào)函數(shù)
onSelectChange = (selectedRowKeys, selectedRows) => {
// console.log(selectedRowKeys);
if (selectedRows.length === 0) {
this.setState({checkboxPropsKey: undefined})
}
this.setState({ selectedRowKeys });
this.props.getSelectData(selectedRows);
};
/**
* 多選設(shè)置
* @param record 列表
* @param key 選擇后不可選key值
* @param unselect 列表不可選設(shè)置
*/
getCheckboxProps = (record, key=undefined, unselect=undefined) => {
if (record !== null && key !== undefined) {
return({
disabled: record.onlyKey !== key, // Column configuration not to be checked
})
}
if (record !== null && key === undefined && unselect !== undefined) {
if (this.state.unselectType) {
return({
disabled: record[unselectPar] === unselect, // 相等時(shí)不可選
})
} else {
return({
disabled: record[unselectPar] !== unselect, // 不等時(shí)不可選
})
}
}
};
render() {
let _this = this.props.tableData;
if (_this.changePageParam && Object.keys(_this.changePageParam).length > 0) {
this.newParam(_this.changePageParam);
}
const tableList = {
pagination: this.state.pagination,
loading: this.state.loading,
};
const { selectedRowKeys } = this.state;
const columns = this.state.columns;
// 多選
const Selection = {
selectedRowKeys,
onChange: this.onSelectChange,
getCheckboxProps: (e) => this.getCheckboxProps(e, this.state.checkboxPropsKey, this.state.unselect),
};
const rowSelection = this.props.tableData.rowSelection ? Selection : null
return (
<div>
<Table
{...tableList}
size={this.state.size}
rowKey={(record, index) => `${record.onlyKey}`}
bordered
dataSource={this.state.data}
rowSelection={rowSelection}
columns={columns}
scroll={this.props.tableData.scroll}
>
</Table>
</div>
)
}
}
// 指定 props 的默認(rèn)值:
TableComponent.defaultProps = {
};
TableComponent.propTypes = { //.propTypes是react規(guī)定的名稱,不可以修改
tableData: PropTypes.shape({
url: PropTypes.string.isRequired, // 路徑類型
rowSelection: PropTypes.bool, // 復(fù)選標(biāo)識(shí)
lineIndex: PropTypes.bool, // 序號(hào)標(biāo)識(shí)
columns: PropTypes.array.isRequired, // 列參數(shù)
dataToOut: PropTypes.bool, // 數(shù)據(jù)外傳標(biāo)識(shí)
addParams: PropTypes.object, // 新增參數(shù)
size: PropTypes.oneOf(['default', 'middle', 'small']), // 表格尺寸
handleOverflow: PropTypes.bool, // 全局溢出處理婶博,不需要再單獨(dú)每個(gè)列設(shè)置(設(shè)置后忽略單獨(dú)設(shè)置)
falseData: PropTypes.array, // 假數(shù)據(jù)
method: PropTypes.oneOf(['get', 'post']), // 請(qǐng)求方式
changePageParam:PropTypes.objectOf(function(propValue, key, componentName, location, propFullName) {
let allowKeys = [ 'pageSize', 'page', 'totalCount', 'list' ]
if (allowKeys.indexOf(key) < 0 ) {
return new Error(
'Invalid prop `' + componentName + '` supplied to' +
' `' + propFullName + '`. Validation failed.'
);
}
}), // 替代頁(yè)面參數(shù)
scroll: PropTypes.object, // 滾動(dòng)配置
}),
// 列新參數(shù)說(shuō)明(由于不知道怎么設(shè)置tableData.columns的參數(shù)類型,
// 所以暫放在這荧飞,但組件沒(méi)有這個(gè)參數(shù))
Columns: PropTypes.shape({
overflow: PropTypes.bool, // 列移除處理(移除顯示省略號(hào)...)
})
};
export default TableComponent;
作為一個(gè)初級(jí)前端工作者凡人,歡迎大家對(duì)我的代碼、思路進(jìn)行指導(dǎo)叹阔,謝謝大家挠轴。