antd表单组件的简易实现
本文代码复制于github某位老师,如有侵权,联系我删除本文主要用于自己学习react组件话不多说,直接上代码:import React, { Component } from "react";import { Icon } from "antd";// hoc:包装用户表单,增加数据管理能力、校验function kFormCreate(Comp) {return class...
·
本文代码复制于github某位老师,如有侵权,联系我删除
本文主要用于自己学习react组件
话不多说,直接上代码:
import React, { Component } from "react";
import { Icon } from "antd";
// hoc:包装用户表单,增加数据管理能力、校验
function kFormCreate(Comp) {
return class NewComp extends Component {
constructor(props) {
super(props);
this.options = {}; //字段选项设置
this.state = {}; //各字段值
}
// 处理表单项输入事件
handleChange = e => {
const { name, value } = e.target;
this.setState(
{
[name]: value
},
() => {
// 数值变化后再校验
this.validateField(name);
}
);
};
// 表单项校验
validateField = field => {
const rules = this.options[field].rules;
//只要任何一项失败就失败
const ret = rules.some(rule => {
if (rule.required) {
//仅验证必填项
if (!this.state[field]) {
// 校验失败
this.setState({
[field + "Message"]: rule.message
});
return true; // 若有校验失败,返回true
}
}
});
if (!ret) {
// 没失败,校验成功
this.setState({ [field + "Message"]: "" });
}
return !ret;
};
// 校验所有字段
validate = cb => {
const rets = Object.keys(this.options).map(field =>
this.validateField(field)
);
// 如果校验结果数组中全部为true,则校验成功
const ret = rets.every(v => v === true);
cb(ret);
};
getFieldDec = (field, option, InputComp) => {
this.options[field] = option;
return (
<div>
{React.cloneElement(InputComp, {
name: field, //控件name
value: this.state[field] || "", //控件值
onChange: this.handleChange, //change事件处理
onFocus: this.handleFocus // 判断控件是否获得焦点
})}
{/* {this.state[field + "Message"] && (
<p style={{ color: "red" }}>{this.state[field + "Message"]}</p>
)} */}
</div>
);
};
//
handleFocus = e => {
const field = e.target.name;
this.setState({
[field + "Focus"]: true
});
};
// 判断组件是否被用户点过
isFieldTouched = field => !!this.state[field + "Focus"];
getFieldError = field => this.state[field + "Message"];
render() {
return (
<Comp
{...this.props}
getFieldDec={this.getFieldDec}
value={this.state}
validate={this.validate}
isFieldTouched={this.isFieldTouched}
getFieldError={this.getFieldError}
/>
);
}
};
}
class FormItem extends Component {
render() {
return (
<div className="formItem">
{this.props.children}
{this.props.validateStatus === "error" && (
<p style={{ color: "red" }}>{this.props.help}</p>
)}
</div>
);
}
}
class KInput extends Component {
render() {
return (
<div>
{/* 前缀图标 */}
{this.props.prefix}
<input {...this.props} />
</div>
);
}
}
@kFormCreate
class KFormSample extends Component {
onSubmit = () => {
this.props.validate(isValid => {
if (isValid) {
alert("校验成功,提交登录");
console.log(this.props.value);
} else {
alert("校验失败");
}
});
};
render() {
const { getFieldDec, isFieldTouched, getFieldError } = this.props;
const userNameError = isFieldTouched("uname") && getFieldError("uname");
const passwordError = isFieldTouched("pwd") && getFieldError("pwd");
return (
<div>
<FormItem
validateStatus={userNameError ? "error" : ""}
help={userNameError || ""}
>
{getFieldDec(
"uname",
{
rules: [{ required: true, message: "请填写用户名" }]
},
<KInput type="text" prefix={<Icon type="user" />} />
)}
</FormItem>
<FormItem
validateStatus={passwordError ? "error" : ""}
help={passwordError || ""}
>
{getFieldDec(
"pwd",
{
rules: [{ required: true, message: "请填写用户名" }]
},
<KInput type="password" prefix={<Icon type="lock" />} />
)}
</FormItem>
<button onClick={this.onSubmit}>登录</button>
</div>
);
}
}
export default KFormSample;
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献1条内容
所有评论(0)