antd移动端使用
安装:
$ npm install --save antd-mobile # or $ yarn add antd-mobile # or $ pnpm add antd-mobile
常用组件使用:
select/picker:

import React, { useState } from 'react'
import { Picker, Button, Space, Toast } from 'antd-mobile'
import { DemoBlock, DemoDescription } from './demos-util'
import { basicColumns } from './columns-data'
// 基础用法
function BasicDemo() {
const [visible, setVisible] = useState(false)
const [value, setValue] = useState<(string | null)[]>(['M'])
return (
<>
<Button
onClick={() => {
setVisible(true)
}}
>
选择
</Button>
<Picker
columns={basicColumns}
visible={visible}
onClose={() => {
setVisible(false)
}}
value={value}
onConfirm={v => {
setValue(v)
}}
/>
</>
)
}
function ActionsDemo() {
const [value, setValue] = useState<(string | null)[]>(['M'])
return (
<Picker
columns={basicColumns}
value={value}
onConfirm={v => {
setValue(v)
}}
>
{(_, actions) => <Button onClick={actions.open}>选择</Button>}
</Picker>
)
}
// 渲染所选值
function RenderChildrenDemo() {
const [value, setValue] = useState<(string | null)[]>([])
return (
<Picker
columns={basicColumns}
value={value}
onConfirm={setValue}
onSelect={(val, extend) => {
console.log('onSelect', val, extend.items)
}}
>
{(items, { open }) => {
return (
<Space align='center'>
<Button onClick={open}>选择</Button>
{items.every(item => item === null)
? '未选择'
: items.map(item => item?.label ?? '未选择').join(' - ')}
</Space>
)
}}
</Picker>
)
}
export default () => {
return (
<>
<DemoBlock title='基础用法'>
<BasicDemo />
</DemoBlock>
<DemoBlock title='渲染所选值'>
<RenderChildrenDemo />
</DemoBlock>
<DemoBlock title='使用 actions 来控制显示/隐藏'>
<Space direction='vertical' block>
<ActionsDemo />
<DemoDescription>
在 children 渲染函数中,你可以使用第二个参数 actions
来非常方便的控制 Picker 的显示或隐藏
</DemoDescription>
</Space>
</DemoBlock>
<DemoBlock title='指令式调用'>
<Button
onClick={async () => {
const value = await Picker.prompt({
columns: basicColumns,
})
Toast.show(`你选择了 ${value}`)
}}
>
弹出 Picker
</Button>
</DemoBlock>
</>
)
}
steps:

import React from 'react' import { Steps } from 'antd-mobile' import { DemoBlock } from './demos-util' const { Step } = Steps export default () => { return ( <> <DemoBlock title='横向步骤条'> <Steps current={2}> <Step
title='标题1'
description='描述'
style={{
/>
<Step title='标题2' description='描述' />
<Step title='标题3' description='描述' />
</Steps>
</DemoBlock>
<DemoBlock title='纵向步骤条'>
<Steps direction='vertical'>
<Step title='填写机构信息' status='process' />
<Step title='签约机构' status='wait' />
<Step title='关联服务区' status='wait' />
</Steps>
</DemoBlock>
</>
)
}
input:

import React, { useState } from 'react'
import { Form, Input } from 'antd-mobile'
import { DemoBlock } from 'demos'
import styles from './demo2.less'
import { EyeInvisibleOutline, EyeOutline } from 'antd-mobile-icons'
export default () => {
const [visible, setVisible] = useState(false)
return (
<>
<DemoBlock title='配合列表使用-水平布局' padding='0'>
<Form layout='horizontal'>
<Form.Item label='用户名' name='username'>
<Input placeholder='请输入用户名' clearable />
</Form.Item>
<Form.Item label='密码' name='password'>
<Input placeholder='请输入密码' clearable type='password' />
</Form.Item>
</Form>
</DemoBlock>
<DemoBlock title='配合列表使用-竖直布局' padding='0'>
<Form layout='vertical'>
<Form.Item label='用户名' name='username'>
<Input placeholder='请输入用户名' clearable />
</Form.Item>
<Form.Item label='密码' name='password'>
<Input placeholder='请输入密码' clearable type='password' />
</Form.Item>
</Form>
</DemoBlock>
<DemoBlock title='带辅助操作' padding='0'>
<Form layout='horizontal'>
<Form.Item
label='短信验证码'
extra={
<div className={styles.extraPart}>
<a>发送验证码</a>
</div>
}
>
<Input placeholder='请输入验证码' clearable />
</Form.Item>
</Form>
</DemoBlock>
<DemoBlock title='带密码可见' padding='0'>
<Form layout='horizontal'>
<Form.Item label='用户名' name='username'>
<Input placeholder='请输入用户名' clearable />
</Form.Item>
<Form.Item
label='密码'
name='password'
extra={
<div className={styles.eye}>
{!visible ? (
<EyeInvisibleOutline onClick={() => setVisible(true)} />
) : (
<EyeOutline onClick={() => setVisible(false)} />
)}
</div>
}
>
<Input
placeholder='请输入密码'
clearable
type={visible ? 'text' : 'password'}
/>
</Form.Item>
</Form>
</DemoBlock>
</>
)
}
form表单校验:

import React, { useState, FC } from 'react'
import { Form, Input, Button, Picker, Space } from 'antd-mobile'
import type { PickerValue } from 'antd-mobile/es/components/picker'
import { DownOutline } from 'antd-mobile-icons'
interface MobileValue {
preValue: string
realValue: string
}
export default () => {
const onFinish = (values: any) => {
console.log(values)
}
const checkMobile = (_: any, value: MobileValue) => {
if (value.realValue) {
return Promise.resolve()
}
return Promise.reject(new Error('手机号不能为空!'))
}
return (
<>
<Form
layout='vertical'
onFinish={onFinish}
initialValues={{
mobile: { preValue: '86', realValue: '' },
}}
footer={
<Button block type='submit' color='primary' size='large'>
提交
</Button>
}
>
<Form.Header>自定义表单控件</Form.Header>
<Form.Item
label='姓名'
name='name'
rules={[{ required: true, message: '姓名不能为空!' }]}
>
<Input placeholder='请输入姓名' />
</Form.Item>
<Form.Item
label='手机号'
name='mobile'
rules={[{ required: true }, { validator: checkMobile }]}
>
<MobileField />
</Form.Item>
</Form>
</>
)
}
const columns = [['86', '01', '02', '03']]
interface MobileFieldProps {
value?: MobileValue
onChange?: (value: MobileValue) => void
}
const MobileField: FC<MobileFieldProps> = ({
value = { preValue: '86', realValue: '' },
onChange,
}) => {
const [visible, setVisible] = useState(false)
const triggerValue = (changedValue: Partial<MobileValue>) => {
onChange?.({ ...value, ...changedValue })
}
const onRealValueChange = (value: string) => {
triggerValue({ realValue: value })
}
const onPreValueChange = (value: PickerValue[]) => {
const v = value[0]
if (v === null) return
triggerValue({ preValue: v })
}
return (
<>
<Space align='center'>
<Space align='center' onClick={() => setVisible(true)}>
<div>+{value.preValue}</div>
<DownOutline />
</Space>
<Input
placeholder='请输入手机号'
value={value.realValue}
onChange={onRealValueChange}
/>
</Space>
<Picker
columns={columns}
visible={visible}
onClose={() => {
setVisible(false)
}}
value={[value.preValue]}
onConfirm={onPreValueChange}
/>
</>
)
}



import React from 'react' import { Form, Input, Button } from 'antd-mobile' import { AddCircleOutline } from 'antd-mobile-icons' export default () => { const onFinish = (values: any) => { console.log(values) } return ( <> <Form onFinish={onFinish} initialValues={{ contacts: [{}], }} footer={ <Button block type='submit' color='primary' size='large'> 提交 </Button> } mode='card' > <Form.Item name={'name'} label='客户名称'> <Input placeholder='请输入客户名称' /> </Form.Item> <Form.Array name='contacts' onAdd={operation => operation.add({ name: '张三' })} renderAdd={() => ( <span> <AddCircleOutline /> 添加 </span> )} renderHeader={({ index }, { remove }) => ( <> <span>联系人{index + 1}</span> <a onClick={() => remove(index)} style={{ float: 'right' }}> 删除 </a> </> )} > {fields => fields.map(({ index }) => ( <> <Form.Item name={[index, 'name']} label='姓名' rules={[{ required: true, message: '姓名不能为空' }]} > <Input placeholder='请输入姓名' /> </Form.Item> <Form.Item name={[index, 'address']} label='地址'> <Input placeholder='请输入地址' /> </Form.Item> </> )) } </Form.Array> </Form> </> ) }

<Form.Item name='birthday' label='Birthday'
trigger='onConfirm'
onClick={(e, datePickerRef: RefObject<DatePickerRef>) => { datePickerRef.current?.open() // ⬅️ }} > <DatePicker> {value => value ? dayjs(value).format('YYYY-MM-DD') : 'Please select' } </DatePicker> </Form.Item>
地区联动组件使用:
import React, { useState } from 'react'
import { Cascader, Button, Space, Toast } from 'antd-mobile'
import { DemoBlock, DemoDescription } from 'demos'
import { options, longOptions } from './data'
// 基础用法
function BasicDemo() {
const [visible, setVisible] = useState(false)
return (
<>
<Button
onClick={() => {
setVisible(true)
}}
>
选择
</Button>
<Cascader
options={options}
visible={visible}
onClose={() => {
setVisible(false)
}}
/>
</>
)
}
// 渲染所选值
function RenderChildrenDemo() {
const [visible, setVisible] = useState(false)
const [value, setValue] = useState<string[]>([])
return (
<Space align='center'>
<Button
onClick={() => {
setVisible(true)
}}
>
选择
</Button>
<Cascader
options={options}
visible={visible}
onClose={() => {
setVisible(false)
}}
value={value}
onConfirm={setValue}
onSelect={(val, extend) => {
console.log('onSelect', val, extend.items)
}}
>
{items => {
if (items.every(item => item === null)) {
return '未选择'
} else {
return items.map(item => item?.label ?? '未选择').join('-')
}
}}
</Cascader>
</Space>
)
}
function ActionsDemo() {
const [value, setValue] = useState<string[]>([])
return (
<Cascader
options={options}
value={value}
onConfirm={v => {
setValue(v)
}}
>
{(_, actions) => <Button onClick={actions.open}>选择</Button>}
</Cascader>
)
}
export default () => {
return (
<>
<DemoBlock title='基础用法'>
<BasicDemo />
</DemoBlock>
<DemoBlock title='渲染所选值'>
<RenderChildrenDemo />
</DemoBlock>
<DemoBlock title='指令式调用'>
<Button
onClick={async () => {
const value = await Cascader.prompt({
options,
title: '选择地址',
})
Toast.show(value ? `你选择了 ${value.join('-')}` : '你没有进行选择')
}}
>
弹出 Cascader
</Button>
</DemoBlock>
<DemoBlock title='长数据'>
<Button
onClick={async () => {
const value = await Cascader.prompt({
options: longOptions,
placeholder: '请选择',
})
Toast.show(
value ? `你选择了 ${value.join(' - ')}` : '你没有进行选择'
)
}}
>
选择
</Button>
</DemoBlock>
<DemoBlock title='使用 actions 来控制显示/隐藏'>
<Space direction='vertical' block>
<ActionsDemo />
<DemoDescription>
在 children 渲染函数中,你可以使用第二个参数 actions
来非常方便的控制 Picker 的显示或隐藏
</DemoDescription>
</Space>
</DemoBlock>
</>
)
}

数据结构:


浙公网安备 33010602011771号