需求
点击确定按钮后,弹出验证码弹框,要求自动获取焦点,输入验证码后弹框关闭原型图长这样:![在这里插入图片描述](https://img-/d9938d36223940afa3a886ad7bd362db.png#pic_center)
这里有两个坑,一个是看上去有6个输入框,其实用一个Input就行,6个方框用样式写在input下面。 第二个是获取焦点,antd的Input组件需要放置form表单里才能获取焦点(也许别的方法也可以,暂时没找到),而且要给form设置useRef。通过ref.current.getFieldInstance().focus()实现获取焦点
首先画出弹框结构
<Modal title="请输入验证码" width={480} zIndex={2000} footer={[]} centered forceRender destroyOnClose maskClosable={false} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}><div className='verify-modal'><Spin spinning={loading} tip="校验中"><div className='modal-body'><div className='modal-tip'>已发送6位验证码至 <a>xxxxxxx</a></div><div className='number-input'>{renderInput()} // 渲染输入框的方法</div></div><div className='modal-footer'><Button shape='round' type='primary'>重新发送</Button></div></Spin></div></Modal>
自定义输入框
因为要实现连续的输入6个数字,所以用一个输入框Input组件,设置opacity: 0;定义position为absolute,将位置覆盖在定义的6个div上
const renderInput = ()=>{return <div className="number-box">{Array(6).fill("").map((_, index) => (<divclassName={`number-item ${isFocus && verifyNumber?.length === index? "isfocus": ""}`}>{verifyNumber[index]}</div> ))}<Form className='input-item' ref={formRef}><Form.Item name="number"><InputmaxLength={6}onChange={onInput}onFocus={onFocus}/> </Form.Item></Form></div>}
样式
.number-box{display: flex;flex-direction: row;justify-content: space-around;margin-top: 32px;margin-bottom: 48px;.number-item{border: 1px solid #E0E0E0;border-radius: 4px;width: 54px;height: 70px;font-weight: 500;font-size: 32px;line-height: 69px;display: flex;justify-content: center;align-items: center;color: #1A1A1A;}.isfocus{border: 1px solid @primary-color;}.input-item{position: absolute;height: 70px;opacity: 0;width: 100%;& .ant-input{height: 70px;}}}
完整代码
import {Button, Col, Form, Input, InputNumber, Modal, Row, Space, Spin } from 'antd'import React, {useEffect, useRef, useState } from 'react'import './index.less'interface infoVerify{isModalOpen: booleanhandleOk:()=>voidhandleCancel:()=>void}const InfoVerify:React.FC<infoVerify> = ({isModalOpen,handleOk,handleCancel}) => {const [loading, setloading] = useState(false)const [verifyNumber, setverifyNumber] = useState<any>('')const [isFocus, setisFocus] = useState(true)const formRef = useRef<any>()useEffect(() => {if(isModalOpen){if(formRef.current){setTimeout(() => {formRef.current.getFieldInstance('number').focus()setisFocus(true)}, 10);}}}, [isModalOpen,formRef])const onFocus = ()=>{setisFocus(true)}const onInput = (e:any)=>{const target = e.target.valuesetverifyNumber(target)if(target?.length>=6){setloading(true)setTimeout(()=>{setloading(false)handleOk()setverifyNumber('')console.log('formRef.current',formRef.current);formRef.current.setFieldsValue({number:''})})}}const renderInput = ()=>{return <div className="number-box">{Array(6).fill("").map((_, index) => (<divclassName={`number-item ${isFocus && verifyNumber?.length === index? "isfocus": ""}`}>{verifyNumber[index]}</div>))}<Form className='input-item' ref={formRef}><Form.Item name="number"><InputmaxLength={6}onChange={onInput}onFocus={onFocus}/> </Form.Item></Form></div>}return (<Modal title="请输入验证码" width={480} zIndex={2000} footer={[]} centered forceRender destroyOnClose maskClosable={false} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}><div className='verify-modal'><Spin spinning={loading} tip="校验中"><div className='modal-body'><div className='modal-tip'>已发送6位验证码至 <a>xxxxxxx</a></div><div className='number-input'>{renderInput()}</div></div><div className='modal-footer'><Button shape='round' type='primary'>重新发送</Button></div></Spin></div></Modal>)}export default InfoVerify