在React
中,react提供了ref来让我们获取react元素对应的真实的dom
元素,利用这个特性我们确实可以获取表单域所对应的值
import React, { Fragment, useRef, useState } from "react";export default function A() {const inputRef = useRef<any>();const [value, setValue] = useState();const onSubmit = () => {setValue(inputRef?.current?.value);};return (<Fragment><input type="text" ref={inputRef} /><button onClick={onSubmit}>提交</button><p>输入的值为: {value}</p></Fragment>);
}
但是显然这中方式在实战中的庞大表单结构中会显得非常无力和麻烦。
如果使用UI框架Ant Design
开发前端应用那么我们可以使用Antd自带的表单体系生成和验证表单:
import { Form, Input, Button, Checkbox } from 'antd';const Demo = () => {const onFinish = (values) => {console.log('Success:', values);};const onFinishFailed = (errorInfo) => {console.log('Failed:', errorInfo);};return (<Formname="basic"labelCol={{span: 8,}}wrapperCol={{span: 16,}}initialValues={{remember: true,}}onFinish={onFinish}onFinishFailed={onFinishFailed}autoComplete="off"><Form.Itemlabel="Username"name="username"rules={[{required: true,message: 'Please input your username!',},]}><Input /></Form.Item><Form.Itemlabel="Password"name="password"rules={[{required: true,message: 'Please input your password!',},]}><Input.Password /></Form.Item><Form.Itemname="remember"valuePropName="checked"wrapperCol={{offset: 8,span: 16,}}><Checkbox>Remember me</Checkbox></Form.Item><Form.ItemwrapperCol={{offset: 8,span: 16,}}><Button type="primary" htmlType="submit">Submit</Button></Form.Item></Form>);
};der(<Demo />, mountNode);
现在我遇到使用MaterialUI(Mui)开发前端项目的需求,Mui并没有自己提供表单的验证功能,因此我现在的做法就是寻求第三方库,调研了一段时间后选择了formik+yup的这样一个解决方案,现在已简单的登录页面表单举例:
import { Box, Checkbox, FormControl, FormControlLabel, TextField } from "@mui/material";
import logo from "../assets/imgs/logo.png";
import MatPassword from "../components/common/material/MatPasword";
import * as Yup from "yup";
import { useFormik } from "formik";
import { LoadingButton } from "@mui/lab";
import { LoginParams } from "../del";export default function Login() {const classes = useStyles();const formik = useFormik({initialValues: {username: "",password: "",remember: true,} as LoginParams,validationSchema: Yup.object({username: Yup.string().email("Must be a valid email").max(255).required("Email is required"),password: Yup.string().max(255).min(5, "sssss").required("Password is required"),}),onSubmit: (values) => {console.log("Send Request", values);},});const login: () => Promise<any> | void = () => {formik.handleSubmit();};return (<Box className={ainer}><div className={t}><div><img src={logo} alt="" width={360} height={130} /></div><Box className={classes.formContainer}><div className={classes.title}>Login to your portal</div><form style={{ width: "100%" }} action=""><FormControl sx={{ width: 1 / 1, "& .MuiTextField-root": { height: 76 } }}><TextFieldonBlur={formik.handleBlur}onChange={formik.handleChange}type="email"name="username"value={formik.values.username}error={uched.username && s.username)}helperText={uched.username && s.username}margin="normal"fullWidthlabel="Email"size="medium"></TextField></FormControl><FormControl sx={{ width: 1 / 1, height: 76 }}><MatPasswordtype="password"onChange={formik.handleChange}onBlur={formik.handleBlur}label="password"value={formik.values.password}error={uched.password && s.password)}helperText={uched.password && s.password}fullWidthname="password"size="medium"></MatPassword></FormControl><FormControl sx={{ width: 1 / 1, height: 56 }}><FormControlLabel control={<Checkbox onBlur={formik.handleBlur} name="remember" onChange={formik.handleChange} checked={ber} />} label="remember" /></FormControl></form><p> </p><LoadingButton sx={{ mb: 3 }} loading={formik.isSubmitting} fullWidth onClick={login} variant="contained">Log in</LoadingButton>{/* <Button onClick={back}>already loged in</Button> */}</Box></div></Box>);
}
从formik官网我们可以了解到在react中使用可以有两种方法:
使用Formik组件:
import React from 'react';
import { Formik, Form, Field } from 'formik';
import * as Yup from 'yup';const SignupSchema = Yup.object().shape({firstName: Yup.string().min(2, 'Too Short!').max(50, 'Too Long!').required('Required'),lastName: Yup.string().min(2, 'Too Short!').max(50, 'Too Long!').required('Required'),email: Yup.string().email('Invalid email').required('Required'),
});export const ValidationSchemaExample = () => (<div><h1>Signup</h1><FormikinitialValues={{firstName: '',lastName: '',email: '',}}validationSchema={SignupSchema}onSubmit={values => {// same shape as initial valuesconsole.log(values);}}>{({ errors, touched }) => (<Form><Field name="firstName" />{errors.firstName && touched.firstName ? (<div>{errors.firstName}</div>) : null}<Field name="lastName" />{errors.lastName && touched.lastName ? (<div>{errors.lastName}</div>) : null}<Field name="email" type="email" />{ail && ail ? <div>{ail}</div> : null}<button type="submit">Submit</button></Form>)}</Formik></div>
);
另一种就是我现在采用的使用useFormik这个hook的模式
useFormik传参为formik的配置项,配置项有:
validationSchema:表单的校验规则:这里就是用第三方库yup
去生成校验规则:
validationSchema: Yup.object({username: Yup.string().email("Must be a valid email").max(255).required("Email is required"),password: Yup.string().max(255).min(5, "sssss").required("Password is required"),
}),
具体配置和使用就参照yup的官方文档(npm上也能找到文档)
这里有一点需要特殊说明:
如果有动态生成表单域以及表单校验规则的需求则需要调用when
方法:
validationSchema: Yup.object({screenLockPwd: Yup.number().required(),permissionPolicy: Yup.number().required(),osUpgrade: Yup.number().required(),minPasswordLength: Yup.number().when("screenLockPwd", { is: 1, then: (schema) => quired().integer().positive() }),
}),// 除此之外,when的第一个参数(依赖项)还可以是数组,以为多个依赖,第二个参数中的is配置项可以是一个值,也可以是一个回调函数
let schema = object({isSpecial: boolean(),isBig: boolean(),count: number().when(['isBig', 'isSpecial'], {is: true, // alternatively: (isBig, isSpecial) => isBig && isSpecialthen: (schema) => schema.min(5),otherwise: (schema) => schema.min(0),}),
});await schema.validate({isBig: true,isSpecial: true,count: 10,
});
上面这个例子中,minPasswordLength字段的校验规则为:
.number(): 必须是number类型的输入
.when(): 条件判断:
参数1: 根据screenLockPwd
字段的值进行判断
参数2: 判断规则:
is: 当screenLockPwd字段的值为1的时候
then: 满足条件执行的配置回调
otherwise: 不满足条件的时候执行的配置回调
在上面的例子中我么可以看到一个表单域组件需要配置很多的props:
<TextFieldonBlur={formik.handleBlur}onChange={formik.handleChange}type="email"name="username"value={formik.values.username}error={uched.username && s.username)}helperText={uched.username && s.username}margin="normal"fullWidthlabel="Email"size="medium"
></TextField>;
这其中name
、value
、onChange
、onBlur
都是重复的配置项,这里formik提供了getFieldProps
方法传入name参数就可以返回这些配置,因此上面的代码可以简写为:
<TextFieldtype="email"error={uched.username && s.username)}helperText={uched.username && s.username}margin="normal"fullWidthlabel="Email"size="medium"{...FieldProps("username")}
></TextField>;
本文发布于:2024-01-30 21:42:36,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170662215723030.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |