- Published on
Ant Design - 光速打造你的管理系統
- Authors
- Name
- Wen Chen
前言
過去幾個月時間,把公司產品供客戶使用的管理後台用 Ant Design 算是完整重構了。
得益於 Antd 的強大,讓我們可以用很短的時間將整個管理系統翻新,心中其實一直想為它寫些什麼, 不過因為 Antd 的 官方文件 實在太完整了,幾乎所有想要的資訊都可以在上面找到,本篇主要會著重在使用經驗與分享,畢竟,它確實值得我大力推廣XD。
備註:我們使用的版本是 4.23.1
,底下皆以這版本為主,某些內容在後續版本可能會獲得更新
Ant Design ?
Ant Design 是由螞蟻集團所推出的用來建構後台系統用的 UI Library,在 Github 上目前有 84.4k 顆星星,而用來做後台的 UI Library 那麼多,Antd 到底有什麼不同?
根據這次負責的專案,功能包含了,「 大量複雜的表單、大量的 Date Picker、Progress、各式各樣的 Table (樹狀、可編輯、排序、分頁) 」,絕大多數的 UI Library,通常只支援 UI 的部分,元件功能上,都需要自己寫或是再另外找 Library 來完成特定需求。
而 Antd 便是符合上述需求的不二人選,使用這幾個月我認為它有一些很大的優點:
- 提供 React Component,且提供的元件種類超乎想像,幾乎沒有遇到無法支援的情境
- Antd 提供的 Form 與其他 Antd 組件搭配非常順暢,提供的 api 也很易用
- 文件非常齊全,不管中文英文都很詳細,幾乎不需要再看教學,照文件做就好
- 更新頻繁,不怕當孤兒
為佐證上面的優點,我們來看下最管理後台使用最頻繁的 Table 文件
光是右側 Example 就提供一~大堆可以參考,每一個都有實際畫面可以操作,功能非常齊全,而且本身設計的就很舒服,極少數情況才需要自幹改樣式,大部分頂多改改寬高、padding、margin 就很夠用了,就算真的需要 override css 也不會太難改。
快速上手重點功能 !
上面簡單介紹了 Antd ,接下來會介紹幾種個人覺得使用 Antd 必用到的功能。
Form
表單是後台管理系統不可或缺的功能,Antd 提供了非常強大的 Form 供使用者使用,在使用上和各元件的整合度也非常高,先上範例:CodeSandBox
簡單把玩過範例後,底下擷取片段說明,完整程式碼請看 CodeSandBox 內:
import { Button, Form, Input, Select } from 'antd';
import React from 'react';
const { Option } = Select;
const App: React.FC = () => {
const [form] = Form.useForm();
const onGenderChange = (value: string) => {
switch (value) {
case 'male':
form.setFieldsValue({ note: 'Hi, man!' });
break;
case 'female':
form.setFieldsValue({ note: 'Hi, lady!' });
break;
case 'other':
form.setFieldsValue({ note: 'Hi there!' });
break;
default:
}
};
const onReset = () => {
form.resetFields();
};
return (
<Form
form={form}
name="control-hooks"
>
<Form.Item name="note" label="Note" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item name="gender" label="Gender" rules={[{ required: true }]}>
<Select
placeholder="Select a option and change input text above"
onChange={onGenderChange}
allowClear
>
<Option value="male">male</Option>
<Option value="female">female</Option>
<Option value="other">other</Option>
</Select>
</Form.Item>
<Form.Item >
<Button type="primary" htmlType="submit">
Submit
</Button>
<Button htmlType="button" onClick={onReset}>
Reset
</Button>
</Form.Item>
</Form>
);
};
export default App;
首先我們分段來解析上面的 Code :
const [form] = Form.useForm()
: 我們使用上會用 antd 提供的 hook 產出一個 form 實例,方便我們傳遞於各組件,以及管理所有數據狀態,使用方式也很易用,只需要傳入 Form 元件本身即可。
const [form] = Form.useForm();
return (
<Form form={form}>
<Sub />
</Form>
);
Form.Item
: 用來將 Input
、Select
等各種元件與 Form 綁定數據:
name
:用來表單 form 表單的 key。label
:畫面顯示的欄位標籤。rule
:規則檢查,此處展示必填規則。
<Form.Item name="note" label="Note" rules={[{ required: true }]}>
<Input />
</Form.Item>
少數元件需綁定
valuePropName
,才可正確吃到資料,如 Switch 或 CheckBox 需綁定valuePropName='checked'
// Switch
<Form.Item name='status' label="Status" valuePropName='checked'>
<Switch />
</Form.Item>
資料管理
完成元件之後,useForm
創建出來的 FormInstance 本身提供很多 api 供資料與狀態管理,底下提幾種常用到的:
setFieldsValue
、setFieldValue
:手動設置 Form 表單內的值,絕大多數會使用 setFieldsValue
可以一次設定多個:
const onGenderChange = (value: string) => {
switch (value) {
case 'male':
form.setFieldsValue({ note: 'Hi, man!' });
break;
case 'female':
form.setFieldsValue({ note: 'Hi, lady!' });
break;
case 'other':
form.setFieldsValue({ note: 'Hi there!' });
break;
default:
}
};
form.resetFields
: 預設會 reset 整個 form ,亦可以傳入 NamePath[]
來 reset 特定欄位。
假如有設置
initialValues
,會重置寫在Form
元件之中的initialValues
而非單純清除。
const onReset = () => {
form.resetFields(NamePath[])
};
接下來我們來講講資料提取的部分:
getFieldValue
: getFieldValue([NamePath])
取得指定 name 的值,使用率不高,但偶爾有奇效。
getFieldsValue
: 大部分會使用 getFieldsValue()
來默認拿到當前 form 裡面現存的值。
const data = form.getFieldsValue()
// 或直接解構使用
const { note , gender } = form.getFieldsValue()
Tips : 要注意,默認拿取現存的值,預設情況下,只會拿到 mounted 的值,不出現在畫面的值是拿不到的
可以透過加上 true 來強制取得所有存於 form 內的資料form.getFieldsValue(true)
validateFields
: 會回傳一個 promise,用來驗證表單時非常好用,成功時會回傳 form 裡的資料,假如有未通過的欄位會自動 reject。
// return sample
validateFields()
.then((values) => {
/*
values:
{
username: 'username',
password: 'password',
}
*/
})
.catch((errorInfo) => {
/*
errorInfo:
{
values: {
username: 'username',
password: 'password',
},
errorFields: [
{ name: ['password'], errors: ['Please input your Password!'] },
],
outOfDate: false,
}
*/
});
以上便是比較常用到的資料獲取方式,值得一提的是,getFieldValue
不像 getFieldsValue
預設只能拿到 mounted 的資料,所以某些時候也可以透過 getFieldValue
來取得沒有 mounted 的 formData。
Form.useWatch
: 一樣是很好用的 hooks 之一,放入要監聽的 name 和 formInstance,Antd 會自動監聽 form 的變化,可以將它視為一個 state,可以拿來更新畫面、甚至是和其他 hooks 組合,使用方式:
// type Form.useWatch = (namePath: NamePath, formInstance?: FormInstance): Value
const [form] = Form.useForm();
const userName = Form.useWatch('username', form);
// 與 useSWR 組合
const { data: options } = useSWR(`/api/user/${userName}`, fetcher);
// 與 useEffect 組合
useEffect(() => {
// ... do something
} , [userName])
Tips:一樣只能監聽 mounted 的資料!
Table
和表單一樣重要的當然是渲染資料的 Table,不囉唆一樣先上官方範例:
const dataSource = [
{
key: '1',
name: 'Mike',
age: 32,
address: '10 Downing Street',
},
{
key: '2',
name: 'John',
age: 42,
address: '10 Downing Street',
},
];
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
];
// component
<Table dataSource={dataSource} columns={columns} />;
從上面範例可以看到 Table 元件本身有兩大重點要傳入:
dataSource
:要傳入 Table 的資料
columns
:Table 的 columns,完整參數可看這裡,和 dataSource
一樣是陣列結構,每個物件即代表一個 column,裡面比較重要的參數有:
title
: column title。key
每個 column 的 unique key,官方文件上有提到,假如有指定dataIndex
的話可以省略。dataIndex
: 有給的話會去抓dataSource
內物件的指定Object Key
,一個蘿菠一個坑,也可以不寫,待會會介紹到。
Table 同時也支援透過 render
來自定義要顯示的內容,不一定只能秀文字,可以是tag
或是任何東西:
// render type : function(text, record, index) {}
const columns = [
{
title:"Tags",
dataIndex:"tags",
key:"tags",
render:(tags: string[]) => (
<>
{tags.map((tag) => (
<Tag color="blue" key={tag}>
{tag}
</Tag>
))}
</>
)}]
render
必須要回傳一個 ReactNode
,而傳入的 params 預設就是 dataIndex
綁定的值,前面有提到,可以不給 dataIndex
,這樣便會直接傳入整個 record
,可以用在該欄位可能需要不同資料來搭配呈現時使用。
這個CodeSandBox有比較完整的 render
使用,可以看看。
Tips : 使用上,我們 dataSource 通常會直接拿 api 回傳的 response 塞進去,但 response 不一定會帶
key
,然而 dataSource 的 key 在這裡是必要的,假如沒給會噴key warning
,這點要注意,當初找這個警告來源找好久QQ
後記
其實原本真的只是想簡單寫個介紹,畢竟官方文件資源真的很豐富,沒想到寫下去才發現有一堆小細節可以分享,礙於篇幅(其實是寫累了),決定把一些更細節的東西放在未來的文章內~
總之,這還是一篇介紹 (推坑) 文,在這段時間的接觸中,雖然也出現過幾次 bug ,但 Antd 本身的更新很頻繁,更新套件版本後都有得到解決,總之目前來說,是個有在維護的項目!不用怕壞了沒人處理!
有需要製作管理後台的朋友們,不仿可以試試看!