Ant Design-Table

看起來複雜了點,不過理解後就還好了。

基本用法

表格會用 <Table /> 來表示,並且接收 dataSourcecolumns 這兩個 props。

dataSourcecolumns 的值都是 Array,來看 code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const dataSource = [
{
key: '1',
name: 'PeaNu',
age: 23,
address: '高雄市'
}
]

const columns = [
{
title: '姓名',
dataIndex: 'name',
key: 'name'
}
]

附註:key 是用來給 React 渲染列表用的,預設是用 key 來表示,但你也可以用 rowKey 來重新定義,後面會再解釋。

首先 dataSource 裡面會放我們要呈現的資料,等一下會跟 columns 來做映射。

columns 中最重要的欄位是 dataIndex,填入的東西就代表 dataSource 中的哪個 key?像上面填了 name,所以就會到 dataSource 找到 name: 'PeaNu' 然後顯示到畫面上;至於 title 的話是表格的欄位名稱。

上面的輸出結果如下:

ant-table-basic

重新設定 key 的值

前面有說 key 這個值是用來給 React 渲染列表用的,不過如果資料是透過 API 取得的話,通常不會有 key 這個欄位,那怎麼辦?

這時候就要在 <Table /> 加上 rowKey 這個屬性,告訴他「我要拿哪個欄位來當做 key」。

舉例來說,假設 API 拿到的資料如下:

1
2
3
4
5
6
7
8
9
10
11
12
const dataSource = [
{
userId: '1',
name: 'PeaNu',
gender: 'M'
},
{
userId: '2',
name: 'PPB',
gender: 'F'
}
]

<Table /> 就會長這樣:

1
<Table rowKey='userId' dataSource={dataSource} columns={columns} />

這樣就可以解決 key 的問題了。

巢狀的資料結構

如果現在資料變成這樣:

1
2
3
4
5
6
7
8
9
10
const dataSource = [
{
name: 'PeaNu',
age: 23,
address: '高雄市',
family: {
wife: 'PPB'
}
}
]

columns 就得這樣寫:

1
2
3
4
5
6
const columns = [
{
title: 'Wife',
dataIndex: ['family', 'wife']
}
]

如果現在又變成這樣:

1
2
3
4
5
6
7
8
9
10
11
12
const dataSource = [
{
name: 'PeaNu',
age: 23,
address: '高雄市',
family: [
{
wife: 'PPB'
}
]
}
]

columns 就得這樣寫:

1
2
3
4
5
6
const columns = [
{
title: 'Wife',
dataIndex: ['family', '0', 'wife']
}
]

重新設定輸出到畫面的值

有時候我們從 API 拿到的值不會想直接放到畫面上,例如:

1
2
3
4
5
6
7
8
9
10
const dataSource = [
{
name: 'PeaNu',
gender: 'M'
},
{
name: 'PPB',
gender: 'F'
}
]

這時候就可以用 render 這個屬性來處理:

1
2
3
4
5
6
7
8
9
10
11
12
13
const columns = [
{
title: 'Name',
dataIndex: 'name'
},
{
title: 'Gender',
dataIndex: 'gender',
render: (typeChar: string): string => {
return typeChar === 'F' ? '女' : '男'
}
}
]

也可以用縮寫的方式來寫:

1
2
3
4
5
6
7
8
9
10
11
12
13
const columns = [
{
title: 'Name',
dataIndex: 'name'
},
{
title: 'Gender',
dataIndex: 'gender',
render(value: string): string {
return value === 'F' ? '女' : '男'
}
}
]

想再任性一點嗎?你甚至可以直接回傳一個 JSX:

1
2
3
4
5
6
7
8
9
10
11
12
13
const columns = [
{
title: 'Name',
dataIndex: 'name'
},
{
title: 'Gender',
dataIndex: 'gender',
render(value: string): React.ReactElement {
return typeChar === 'M' ? <h1></h1> : <h1></h1>
}
}
]

加上事件處理

除了 dataSourcecolumns 以外,還有一個 onRow 屬性可以用,用起來會像這樣子:

1
2
3
4
5
6
7
8
9
10
11
12
<Table
dataSource={testData}
columns={testColumns}
onRow={(record: any) => {
return {
onClick: (event) => {
console.log('record', record)
console.log('click')
}
}
}}
/>

onRow 會放一個 function,這個 function 會回傳一個物件,裡面就可以放 event 跟 handler。

至於 record 的值會是觸發事件的「那個欄位」的 dataSource 值。

我知道聽起來講超級無敵難懂,所以一步一步來解釋吧。

假設 dataSource 長這樣:

1
2
3
4
5
6
7
8
9
10
const dataSource = [
{
name: 'PeaNu',
gender: 'M'
},
{
name: 'PPB',
gender: 'F'
}
]

然後我點了 PeaNu 那一排:

ant-table-event

record 的值就會是:

1
2
3
4
{
name: 'PeaNu',
gender: 'M'
}

加上滾軸

如果沒有做額外設定的話,預設的 <Table /> 會「自適應」做縮放,直到放不下時,會在視窗產生滾軸,像這樣:

ant-table-scroll

有沒有辦法讓滾軸產生在「表格中」就好?還真的有,就是加上 scroll 屬性:

1
2
3
4
5
6
7
8
9
<Table
rowKey='id'
dataSource={testData}
columns={testColumns}
scroll={{
x: 1000,
y: 150
}}
/>

裡面要傳一個物件,然後指定 x 軸和 y 軸的「寬度」。這兩個的行為不太一樣,要分清楚。

y 軸的概念比較簡單,想成是總高度就好。例如我設為 150,那表格的高度就會固定成 150px,當資料超過 150px 的話就會產生滾軸。

ant-table-scroll-y

至於 x 軸的部分,你可以這樣記「當視窗小於 x 時,我希望表格的寬度有多寬」。所以我設為 1000 時,就代表當視窗寬度低於 1000 時表格的寬度會固定在 1000px,然後產生滾軸。

ant-table-scroll-x

這樣會好記一點,所以這樣記就好。

加上排序和過濾

如果我有這樣的表格:

ant-table-sort

我希望可以加上升冪跟降冪排序的選項,那我可以在 columns 加上這樣的設定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const columns = useRef([
{
title: 'User id',
dataIndex: 'id',
// 這個就跟 array.sort 的用法一樣
sorter: (a: any, b: any) => a.id - b.id
},
{
title: 'First name',
dataIndex: 'first_name'
},
{
title: 'Last name',
dataIndex: 'last_name'
},
{
title: 'Email',
dataIndex: 'email'
}
])

也可以加上預設值,不過要注意一下 type 的問題,沒設定好的話會出錯:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 記得指定 type,否則會出錯
const columns = useRef<any[]>([
{
title: 'User id',
dataIndex: 'id',
sorter: (a: any, b: any) => a.id - b.id,
// ascend | descend
defaultSortOrder: 'ascend'
},
{
title: 'First name',
dataIndex: 'first_name'
},
{
title: 'Last name',
dataIndex: 'last_name'
},
{
title: 'Email',
dataIndex: 'email'
}
])

接著,如果我希望加上過濾的功能,像這樣:

ant-table-filter

那就要在 columns 上加上兩個東西:

  1. filters,一個 Array
  2. onFilter,一個 function

一樣來看 code 解釋:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const columns = useRef<any[]>([
{
title: 'User id',
dataIndex: 'id'
},
{
title: 'First name',
dataIndex: 'first_name',
// 用來顯示下拉選單的「顯示文字」跟「資料值」
filters: [
{
text: 'George',
value: 'George'
},
{
text: 'Janet',
value: 'Janet'
},
{
text: 'Emma',
value: 'Emma'
}
],
onFilter: (value: any, record: any) => {
// record 會遍歷 dataSource 的每一筆資料
// value = filters 中設定的值
console.log('value', value)
console.log('record', record)
console.log('filter', record.first_name === value)
// 這邊想成是 Array.filter 的邏輯就好
return record.first_name === value
}
},
{
title: 'Last name',
dataIndex: 'last_name'
},
{
title: 'Email',
dataIndex: 'email'
}
])

這樣就可以實現過濾的功能了。

結尾

最後綜合以上所學,我做了一個簡單的範例,有需要的話可以去參考看看。

Ant Design-Breadcrumb 再探 mobx,換個口味的寫法
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×