前言:以下內容基於React全家桶+AntD實戰課程的學習實踐過程記錄。最終成果github地址:https://github.com/66Web/react-antd-manager,歡迎star。
一、基礎表格

- Table組件基礎Api
- bordered屬性:是否展示外邊框和列邊框
- columns屬性:表格列的配置描述(即表頭)
- dataSource屬性:數據數組
- pagination屬性:分頁器,設為 false 時不展示和進行分頁
<Card title="基礎表格"> <Table bordered columns={columns} dataSource={this.state.dataSource} pagination={false} /> </Card>
-
Table基本用法
-
render()中:定義columns表頭配置信息數組
const columns = [ { title: 'id', //表頭標題 dataIndex: 'id' //數據源 }, { title: '用戶名', dataIndex: 'userName' }, { title: '性別', dataIndex: 'sex', render(sex){ return sex === 1 ? '男' : '女' } }, { title: '狀態', dataIndex: 'state', render(state){ let config = { '1': '咸魚一條', '2': '人民公仆', '3': '醫院護士', '4': '科技公司FE', '5': '創業者' } return config[state] } }, { title: '愛好', dataIndex: 'interest', render(abc){ let config = { '1': '游泳', '2': '打籃球', '3': '踢足球', '4': '跑步', '5': '爬山', '6': '騎行', '7': '桌球', '8': '麥霸' } return config[abc] } }, { title: '生日', dataIndex: 'birthday' }, { title: '地址', dataIndex: 'address' }, { title: '早起時間', dataIndex: 'time' } ] - componentDidMount()中:指定表格的數據源
dataSource為一個數組const dataSource = [ //數據源 { id: '0', userName: 'Elena', sex: '1', state: '1', interest: '1', birthday: '2019-01-01', address: '西虹市海淀區桃花公園', time: '07:00' }, { id: '1', userName: 'Mary', sex: '1', state: '2', interest: '3', birthday: '2019-01-01', address: '西虹市海淀區桃花公園', time: '07:00' }, { id: '2', userName: 'Tom', sex: '2', state: '3', interest: '4', birthday: '2019-01-01', address: '西虹市海淀區桃花公園', time: '07:00' } ] -
報錯:原因是數據需要指定唯一key值;使用 map 循環遍歷可以快速添加key值
-
注意:定義好數據源后,必須通過this.setState將dataSource添加到state中
state={} componentDidMount(){ const dataSource= [……], dataSource.map((item, index) => { item.key = index; }) this.setState({ dataSource }) }
二、動態數據渲染表格

- 動態渲染數據
- 在線工具模擬數據:Easy Mock用法及Mock.js規范

-
生成數據

-
src->axios->index.js:定義ajax方法,封裝axios異步獲取Easy Mock項目虛擬數據的過程【項目工程化】
import axios from 'axios' import { Modal } from 'antd'; export default class Axios{ …… static ajax(options){ let baseApi = 'https://www.easy-mock.com/mock/5c2c7c1b580d6209d1e2aa88/mockapi' return new Promise((resolve,reject) => { axios({ url: options.url, method:'get', baseURL: baseApi, timeout: 5000, params: (options.data && options.data.params) || '' }).then((response)=>{ if(response.status === 200){ let res = response.data; if(res.code === 0){ resolve(res); }else{ Modal.info({ title: '提示', content: res.msg }) } }else{ reject(response.data) } }) }); } }注意:根據返回的response獲取數據信息時,要按照Easy Mock中定義的數據結構而定!!!
-
baseTable.js中:定義request方法,調用axios動態獲取Mock數據
import axios from './../../axios/index' state = { dataSource2: [] } params = { page: 1 } //動態獲取mock數據 request = () => { let _this = this; axios.ajax({ url: '/table/list', data:{ params:{ page: this.params.page } } }).then((res) => { if(res.code === 0){ res.list.map((item, index) => { item.key = index }) this.setState({ dataSource2: res.list }) } }) } -
Table組件中:指定數據源為動態獲取到的dataSource2
<Card title="Mock-動態數據渲染表格" style={{margin: '10px 0'}}> <Table bordered columns={columns} dataSource={this.state.dataSource2} pagination={false} /> </Card>
三、表格單選

- rowSelection屬性:列表項是否可選擇,對象
- 配置項:
- type:單選/多選
- selectedRowKeys:指定選中項的key數組,需要和onChange進行配合(單選,僅onRow事件即可)
const selectedRowKeys = this.state.selectedRowKeys; const rowSelection = { type: 'radio', selectedRowKeys }
-
onRow事件:控制點擊某一行,設置行屬性
<Card title="Mock-單選" style={{margin: '10px 0'}}> <Table bordered rowSelection={rowSelection} onRow={(record, index) => { return { onClick: () => { this.onRowClick(record, index) } //點擊行 } }} columns={columns} dataSource={this.state.dataSource2} pagination={false} /> </Card>提取出onRowClick方法:獲取當前點擊行的數據項record和索引index
//點擊某一行 record:當前點擊行的數據項 index:當前點擊行的索引 onRowClick = (record, index) => { let selectKey = [index]; Modal.info({ title: '信息', content: `用戶名:${record.userName},用戶愛好:${record.interest}` }); this.setState({ selectedRowKeys: selectKey, selectedItem: record }) }
四、表格復選

- 配置rowSelection屬性對象
- 添加onChange事件
- selectedRowKeys:當前選中的行索引
- selectedRows:當前選中的行對象
const rowCheckSelection = { type: 'checkbox', selectedRowKeys, onChange: (selectedRowKeys, selectedRows) => { // let ids = [] // selectedRows.map((item) => { // ids.push(item.id) // }) this.setState({ selectedRowKeys, //必需 // selectedIds: ids, selectedRows }) } }
-
選中多行執行操作
-
獲取state中的seletedRows對象,遍歷得到item對象
- 利用item.id執行操作
-
執行完操作,需要重新刷新頁面:調用this.request()
//多選執行刪除動作 handleDelete = () => { let rows = this.state.selectedRows; let ids = []; rows.map((item) => { ids.push(item.id) }) Modal.confirm({ title: '刪除提示', content: `您確定要刪除這些數據嗎?${ids.join(',')}`, onOk: () => { message.success('刪除成功') this.request(); //重新刷新頁面 } }) } -
request方法中:當獲取數據成功后,重置state中當前選中項參數均為空
selectedRowKeys: [], //重置 selectedRows: null,
-
其它,同單選
<Card title="Mock-復選" style={{margin: '10px 0'}}> <div style={{marginBottom: 10}}> <Button onClick={this.handleDelete}>刪除</Button> </div> <Table bordered rowSelection={rowCheckSelection} onRow={(record, index) => { return { onClick: () => { this.onRowClick(record, index) } //點擊行 } }} columns={columns} dataSource={this.state.dataSource2} pagination={false} /> </Card>
五、表格分頁

- src->utils->utils.js:封裝pagination分頁工具函數 【項目工程化】
pagination(data,callback){ return { onChange: (current) => { callback(current) //回調函數返回當前頁 }, current: data.page, pageSize: data.page_size, total: data.total, showTotal: () => { return `共${data.total}條` }, showQuickJumper: true //是否快速跳轉至某一頁 } }注意:獲取data對象的數據,需要符合Easy Mock中模擬數據的數據結構!!!
-
request方法中:當獲取數據成功后,調用Utils.pagination()給state添加並配置pagination
import Utils from './../../utils/utils' let _this = this; //保留外層this,否則this指向會有問題 pagination: Utils.pagination(res,(current) => { _this.params.page = current; this.request(); }) -
Table組件中使用pagination屬性
<Card title="Mock-表格分頁" style={{margin: '10px 0'}}> <Table bordered columns={columns} dataSource={this.state.dataSource2} pagination={this.state.pagination} /> </Card>
六、Loading攔截加載項
- index.html中:在<div id="root"></div>下配置全局html文件 【項目工程化】
<div class="ajax-loading" id="ajaxLoading" style="display: none;"> <div class="overlay"></div> <div class="loading"> <img src="https://media.number-7.cn/ebike-h5/static/images/common/loading.gif" alt=""> <span>加載中,請稍后...</span> </div> </div> -
src->style->loading.less:同時 common.less中引入
/** load **/ .ajax-loading{ display: none; .loading{ position: fixed; top: 50%; left: 50%; transform: translate(-50%,-50%); padding:0 40px; height: 80px; line-height: 80px; background: rgba(0, 0, 0, 0.75); border-radius: 6px; text-align: center; z-index: 9999; font-size:@fontD; color:#fff; img{ width: 32px; vertical-align: middle; } span{ margin-left:12px; } } .overlay{ position: fixed; left: 0; right: 0; top: 0; bottom: 0; z-index: 9998; background: rgb(255, 255, 255); opacity: 0.1; } }@import './../style/loading.less';
-
src->axios->index.js:ajax方法中設置loading默認display block,當獲取數據成功后,改為display none
let loading; if(options.data && options.data.isShowLoading !== false){ loading = document.getElementById('ajaxLoading'); loading.style.display = 'block'; } //其它代碼 .then((response)=>{ if(options.data && options.data.isShowLoading !== false){ loading = document.getElementById('ajaxLoading'); loading.style.display = 'none'; }
七、實例代碼
- pages->table->basicTable.js:對應路由/admin/table/basic
import React from 'react';
import {Card, Table, Modal, Button, message} from 'antd';
import axios from './../../axios/index'
import Utils from './../../utils/utils'
export default class BasicTables extends React.Component{
state = {
dataSource2: []
}
params = {
page: 1
}
componentDidMount(){
const dataSource = [ //數據源
{
id: '0',
userName: 'Elena',
sex: '1',
state: '1',
interest: '1',
birthday: '2019-01-01',
address: '西虹市海淀區桃花公園',
time: '07:00'
},
{
id: '1',
userName: 'Mary',
sex: '1',
state: '2',
interest: '3',
birthday: '2019-01-01',
address: '西虹市海淀區桃花公園',
time: '07:00'
},
{
id: '2',
userName: 'Tom',
sex: '2',
state: '3',
interest: '4',
birthday: '2019-01-01',
address: '西虹市海淀區桃花公園',
time: '07:00'
}
]
dataSource.map((item, index) => {
item.key = index;
})
this.setState({
dataSource
})
this.request();
}
//動態獲取mock數據
request = () => {
let _this = this;
axios.ajax({
url: '/table/list',
data:{
params:{
page: this.params.page
},
// isShowLoading: false
}
}).then((res) => {
if(res.code === 0){
res.list.map((item, index) => {
item.key = index
})
this.setState({
dataSource2: res.list,
selectedRowKeys: [], //重置
selectedRows: null,
pagination: Utils.pagination(res,(current) => {
_this.params.page = current;
this.request();
})
})
}
})
}
onRowClick = (record, index) => {
let selectKey = [index];
Modal.info({
title: '信息',
content: `用戶名:${record.userName},用戶愛好:${record.interest}`
});
this.setState({
selectedRowKeys: selectKey,
selectedItem: record
})
}
// add = () => {
// let item = this.state.selectedItem;
// if(item.id){
// }
// }
//多選執行刪除動作
handleDelete = () => {
let rows = this.state.selectedRows;
let ids = [];
rows.map((item) => {
ids.push(item.id)
})
Modal.confirm({
title: '刪除提示',
content: `您確定要刪除這些數據嗎?${ids.join(',')}`,
onOk: () => {
message.success('刪除成功')
this.request(); //重新刷新頁面
}
})
}
render(){
const columns = [
{
title: 'id', //表頭標題
dataIndex: 'id' //數據源
},
{
title: '用戶名',
dataIndex: 'userName'
},
{
title: '性別',
dataIndex: 'sex',
render(sex){
return sex === 1 ? '男' : '女'
}
},
{
title: '狀態',
dataIndex: 'state',
render(state){
let config = {
'1': '咸魚一條',
'2': '人民公仆',
'3': '醫院護士',
'4': '科技公司FE',
'5': '創業者'
}
return config[state]
}
},
{
title: '愛好',
dataIndex: 'interest',
render(abc){
let config = {
'1': '游泳',
'2': '打籃球',
'3': '踢足球',
'4': '跑步',
'5': '爬山',
'6': '騎行',
'7': '桌球',
'8': '麥霸'
}
return config[abc]
}
},
{
title: '生日',
dataIndex: 'birthday'
},
{
title: '地址',
dataIndex: 'address'
},
{
title: '早起時間',
dataIndex: 'time'
}
]
const selectedRowKeys = this.state.selectedRowKeys;
const rowSelection = {
type: 'radio',
selectedRowKeys
}
const rowCheckSelection = {
type: 'checkbox',
selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
// let ids = []
// selectedRows.map((item) => {
// ids.push(item.id)
// })
this.setState({
selectedRowKeys, //必需
// selectedIds: ids,
selectedRows
})
}
}
return (
<div>
<Card title="基礎表格">
<Table
bordered
columns={columns}
dataSource={this.state.dataSource}
pagination={false}
/>
</Card>
<Card title="Mock-動態數據渲染表格" style={{margin: '10px 0'}}>
<Table
bordered
columns={columns}
dataSource={this.state.dataSource2}
pagination={false}
/>
</Card>
<Card title="Mock-單選" style={{margin: '10px 0'}}>
<Table
bordered
rowSelection={rowSelection}
onRow={(record, index) => {
return {
onClick: () => {
this.onRowClick(record, index)
} //點擊行
}
}}
columns={columns}
dataSource={this.state.dataSource2}
pagination={false}
/>
</Card>
<Card title="Mock-復選" style={{margin: '10px 0'}}>
<div style={{marginBottom: 10}}>
<Button onClick={this.handleDelete}>刪除</Button>
</div>
<Table
bordered
rowSelection={rowCheckSelection}
onRow={(record, index) => {
return {
onClick: () => {
this.onRowClick(record, index)
} //點擊行
}
}}
columns={columns}
dataSource={this.state.dataSource2}
pagination={false}
/>
</Card>
<Card title="Mock-表格分頁" style={{margin: '10px 0'}}>
<Table
bordered
columns={columns}
dataSource={this.state.dataSource2}
pagination={this.state.pagination}
/>
</Card>
</div>
)
}
}
注:項目來自慕課網
