「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。
重新封装input组件,优化用户操作体验
起初,表单是由一个个input组成,当所有表单填写完毕后,点击保存按钮提交数据;要么是下面这样的;要么是弹出一个model,在里面进行编辑保存操作
随着时代的发展,用户体验也越来越严格,优化为这样子↓↓↓
-
默认显示表单value文字
-
鼠标移入显示hover编辑样式
- 鼠标点击,触发input焦点
- 失去焦点,正则验证,保存数据,切换为文字样式
父组件
- 引入,控制表单提交事件,子组件更新表单的值后,发送给父组件,提交数据即可
import BlurInput from "./blur-input";
onEditConsume(cname,consumer){
// 保存信息事件
axios.post(url,修改后的表单全部参数对象)
message.info(cname + "保存成功");
}
- 使用优化后的组件
<BlurInput
cname="姓名"
fieldName="name"
maxLength={8}
value={this.state.consumer.name}
consumer={this.state.consumer}
onSubmit={this.onEditConsumer}
></BlurInput>
封装后的input组件
- 设置标题文字最小宽度 = (文字长度 * 文字大小) + 文字大小(冒号)
let titleLen = this.state.cname.length
let fontSize = 15
this.setState({
titleMinWidth: (fontSize * titleLen) + fontSize
})
- 点击文字,切换为input表单获取焦点
this.textInput = React.createRef();
this.onConsumerInfoClick = this.onConsumerInfoClick.bind(this);
onConsumerInfoClick = async a => {
this.setState({
isShowText: false
});
setTimeout(() => {
this.textInput.current.focus();
}, 222);
}
下方为全部代码,可以体验
import {
Input,
Select,
Icon,
message
} from "antd";
const Option = Select.Option;
import './blur-input.less'
class BlurInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
this.onConsumerInfoClick = this.onConsumerInfoClick.bind(this);
this.state = {
...props,
isShowText: true, //默认线显示文本信息
titleMinWidth: 0 // 根据标题文字设置最小宽度
}
}
componentDidMount() {
this.onInit()
}
onInit() {
// 文字最小宽度 = (文字长度 * 文字大小) + 文字大小(冒号)
let titleLen = this.state.cname.length
let fontSize = 15
this.setState({
titleMinWidth: (fontSize * titleLen) + fontSize
})
}
onConsumerInfoClick = async a => {
this.setState({
isShowText: false
});
if (this.state.type == "select") return;
setTimeout(() => {
this.textInput.current.focus();
}, 222);
};
onConsumerInputChange = async e => {
let key = e.target.name;
let a = this.state.consumer;
this.setState({
value: e.target.value,
consumer: Object.assign(a, { [key]: e.target.value })
});
};
onConsumerInputBlur = async e => {
let { value } = e.target;
if (this.state.regexp && !this.state.regexp.test(value)) {
message.error(this.state.cname + "格式有误");
return this.onConsumerInfoClick();
}
//调用父组件方法,提交数据
value && this.props.onSubmit(this.state.cname, this.state.consumer);
this.setState({
isShowText: true
});
};
render() {
return <div className="blur-input-wrap" style={this.state.style}>
<div
className="t"
style={{ minWidth: this.state.titleMinWidth }}
>{this.state.cname}:</div>
{this.state.isShowText ? (
<div
className="i lyh-fsb"
onClick={this.onConsumerInfoClick}
>
{this.state.value}
<Icon
className="isshow-editico"
type="edit"
theme="twoTone"
/>
</div>
)
:
(
<div className="i lyh-fsb">
<Input
className="i lyh-fsb"
name={this.state.fieldName}
maxLength={this.state.maxLength}
ref={this.textInput}
value={this.state.value}
onChange={e => this.onConsumerInputChange(e)}
onBlur={e => this.onConsumerInputBlur(e)}
></Input>
</div>
)}
</div>
}
}
export default BlurInput;
css代码
.blur-input-wrap {
font-size: 15px;
font-weight: 400;
width: 222px;
width: 224px;
display: flex;
align-items: center;
margin-bottom: 16px;
// padding-right: 15px;
.t {
color: #b5b5b5;
}
.no-hover {
color: #5a5a5a;
padding: 5px;
}
.i {
color: #5a5a5a;
width: 100%;
padding: 5px;
margin-right: 3px;
overflow: hidden;
white-space: nowrap;
.isshow-editico {
display: none;
}
&:hover {
cursor: pointer;
background-color: #f4f9ff;
overflow-x: auto;
.isshow-editico {
display: block;
}
}
}
}
.lyh-fsb {
display: flex;
justify-content: space-between;
align-items: center;
}
客官记得点个赞哦😯😯😯!!!如有问题,欢迎评论区指正