表單看似簡單,卻充滿各種細節。
基本結構
基本結構會由 Form
、Form.item
和 Input(表單相關元件)
來組成。
這邊會用一個登入表單來做講解:
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| import React from 'react'; import { Row, Col, Form, Input ,Button, Checkbox, Space, notification} from "antd"; import { UserOutlined } from "@ant-design/icons";
function Main() {
const onFinish = (values: any) => { notification.success({ message: 'Success!', description: ` username: ${values.username}, password: ${values.passowrd}, remember: ${values.remember} ` }) }
const onFinishFailed = (errorInfo: any) => { notification.error({ message: 'Failed', description: ` Please cofirm your content are vaild. ` }) }
return ( <> <Row> <Col offset={6} span={12}> <h2><Space><UserOutlined />Log in</Space></h2> <Form name="basic" {/* input 的格線 */} wrapperCol={{span: 24}} {/* label 文字的格線 */} labelCol={{span: 24}} {/* 初始值 */} initialValues={{ remember: true }} onFinish={onFinish} onFinishFailed={onFinishFailed} autoComplete="off" > <Form.Item {/* 要顯示的文字 */} label="Username" // data 的 key name="username" rules={[ { {/* 是否必填 */} required: true, {/* 錯誤訊息文字 */} message: 'Please input your username' } ]} > <Input /> </Form.Item> <Form.Item {/* 要顯示的文字 */} label="Password" {/* data 的 key */} name="passowrd" rules={[ { {/* 是否必填 */} required: true, {/* 錯誤訊息文字 */} message: 'Please input your password' } ]} > {/* 提醒一下,密碼要寫成這樣 */} <Input.Password /> </Form.Item> <Form.Item name="remember" {/* 不太懂文件意思,總之加上去後資料跟畫面才會是同步的 */} valuePropName='checked' > <Checkbox>Remember me</Checkbox> </Form.Item> <Form.Item> <Row justify='end'> <Col><Button type='primary' htmlType='submit'>Submit</Button></Col> </Row> </Form.Item> </Form> </Col> </Row> </> ); }
export default Main;
|
這個範例有用到的東西:
onFinish
通過驗證的 handler
onFinishFailed
沒通過驗證的 handler
<Form wrapperCol />
對底下的所有 <input />
做佈局設定
<Form labelCol />
對底下的所有 label
文字做佈局設定
<Form initialValues />
欄位的初始值
<Form.Item label />
label 文字
<Form.Item name />
資料的 key 值
<Form.Item rules />
跟驗證相關的東西 & 提示訊息
<Form.Item valuePropName />
會用到 check 的話要記得設定這個
Radio
會由 Radio.Group
和 Group
來組成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import React, { useState } from 'react' import { Form, Input, Button, Radio } from 'antd' import { UserOutlined } from '@ant-design/icons'
function Main() { const [value, setValue] = useState(1) const onChange = (e: any) => setValue(e.target.value)
return ( <> <Radio.Group name='type' onChange={onChange} value={value}> <Radio value={1}>A</Radio> <Radio value={2}>B</Radio> <Radio value={3}>C</Radio> <Radio value={4}>D</Radio> </Radio.Group> </> ) }
export default Main
|
也可以改用 options
的方式來設定:
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
| import React, { useState } from 'react'; import { Form, Input ,Button, Radio } from "antd"; import { UserOutlined } from "@ant-design/icons";
function Main() { const options = [ { label: 'A', value: 1, disabled: false }, { label: 'B', value: 2, disabled: false }, { label: 'C', value: 3, disabled: false }, { label: 'D', value: 4, disabled: false }, { label: 'E', value: 5, disabled: true } ] const [value, setValue] = useState(1); const onChange = (e: any) => setValue(e.target.value);
return <Radio.Group name="type" onChange={onChange} value={value} options={options} /> ); }
export default Main;
|
Checkbox
基本用法,跟 Radio
差不多。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import React, { useState } from 'react' import { Form, Input, Button, Checkbox } from 'antd' import { UserOutlined } from '@ant-design/icons'
function Main() { const [value, setValue] = useState(1) const onChange = (e: any) => setValue(e.target.value)
return ( <Checkbox.Group name='options'> <Checkbox value={1}>Option1</Checkbox> <Checkbox value={2}>Option2</Checkbox> <Checkbox value={3}>Option3</Checkbox> </Checkbox.Group> ) }
export default Main
|
一次全選
直接看 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
| import React, { useState } from 'react' import { Checkbox } from 'antd'
const plainOptions = ['Apple', 'Orange', 'Pear'] const defaultCheckList = ['Apple', 'Orange']
function Main() { const [indeterminate, setIndeterminate] = useState(true) const [checkAll, setCheckAll] = useState(false) const [checkList, setCheckList] = useState(defaultCheckList)
const onCheckAllChange = (e: any) => { setCheckList(e.target.checked ? plainOptions : []) setIndeterminate(false) setCheckAll(e.target.checked) }
const onChnage = (list: any) => { setCheckList(list) setIndeterminate(!!list.length && list.length < plainOptions.length) setCheckAll(list.length === plainOptions.length) }
return ( <> <Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}> Check All </Checkbox> {/* 改用 options 渲染 */} <Checkbox.Group name='options' options={plainOptions} value={checkList} onChange={onChnage} /> </> ) }
export default Main
|
下拉選單
會由 Select
和 Optnio
來組成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import React, { useState } from 'react' import { Select } from 'antd'
const { Option } = Select
function Main() { const handleChange = (value: string) => console.log(value)
return ( <Select defaultValue='peanu' onChange={handleChange}> <Option value='peanu'>PeaNU</Option> <Option value='ppb'>PPB</Option> <Option value='et'>ET</Option> <Option value='garry'>Garry</Option> </Select> ) }
export default Main
|
改用 optnios
屬性來渲染(據說效能比較好):
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
| import React, { useState } from 'react' import { Select } from 'antd'
const options = [ { label: 'PeaNu', value: 'peanu' }, { label: 'PPB', value: 'ppb' }, { label: 'ET', value: 'et' }, { label: 'Garry', value: 'garry' } ]
function Main() { const handleChange = (value: string) => console.log(value)
return ( <> <Select options={options} defaultValue='peanu' onChange={handleChange} /> </> ) }
export default Main
|
1 2 3 4 5 6
| <Input readOnly={true} /> <Input disabled={true} /> <Input maxLength={20} /> <Input showCount={true} /> <Input prefix={<UserOutlined />} /> <Input suffix={<UserOutlined />}/>
|
改變 password 的 icon:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import React, { useState } from 'react' import { Input } from 'antd' import { EyeFilled, EyeInvisibleFilled } from '@ant-design/icons'
function Main() { return ( <> <Input.Password iconRender={(visible: boolean) => { return visible ? <EyeFilled /> : <EyeInvisibleFilled /> }} /> </> ) }
export default Main
|
initialValues 設定欄位的初始值
附註:提醒一下,key
會對應到 Form.Item
的 name
屬性
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
| import React, { useState } from 'react' import { Input, Form, Radio } from 'antd' import { EyeFilled, EyeInvisibleFilled } from '@ant-design/icons'
const initialValues = { username: 'PeaNu', password: '123456789', gender: 'man' }
function Main() { return ( <> <Form autoComplete='off' initialValues={initialValues}> <Form.Item label='Username' name='username'> <Input /> </Form.Item> <Form.Item label='Passowrd' name='password'> <Input.Password /> </Form.Item> <Form.Item name='gender'> <Radio.Group> <Radio value='man'>Man</Radio> <Radio value='female'>Female</Radio> </Radio.Group> </Form.Item> </Form> </> ) }
export default Main
|
validateTrigger
如名,設定什麼時候觸發驗證的 handler,預設是 onChange
。
如果我想讓 onBlur
時也觸發,可以這樣做:
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 43 44
| import React from 'react' import { Input, Form, Radio } from 'antd'
function Main() { return ( <> {/* 加上 validateTrigger */} <Form autoComplete='off' validateTrigger={['onBlur', 'onChnage']}> <Form.Item label='Username' name='username' rules={[ { required: true, message: 'Please input the username' } ]} > <Input /> </Form.Item> <Form.Item label='Passowrd' name='password' rules={[ { required: true, message: 'Please input the password' } ]} > <Input.Password /> </Form.Item> <Form.Item name='gender'> <Radio.Group> <Radio value='man'>Man</Radio> <Radio value='female'>Female</Radio> </Radio.Group> </Form.Item> </Form> </> ) }
export default Main
|
這個要搭配 useForm()
來使用,它會回傳一個 instance,可以拿這個 instance 做一些事情。例如:當你想一次設定很多個欄位的預設值
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
| import React from 'react' import { Form, Input, Button } from 'antd'
function Main() { const [form] = Form.useForm()
form.setFieldsValue({ username: 'PeaNu', password: '123456789' })
return ( <> {/* 記得要放到 form 屬性裡 */} <Form form={form} autoComplete='off'> <Form.Item label='Username' name='username'> <Input /> <Input.Search /> </Form.Item> <Form.Item label='Password' name='password'> <Input.Password /> </Form.Item> </Form> {/* 點擊時顯示所有欄位的資料 */} <Button onClick={() => console.log(form.getFieldsValue())}>Check data</Button> </> ) }
export default Main
|
因為可以用的東西很多就不一一列出,有需要的話參考這裡。