Ant Design Input组件-优化表单提交体验

412 阅读2分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。

重新封装input组件,优化用户操作体验

起初,表单是由一个个input组成,当所有表单填写完毕后,点击保存按钮提交数据;要么是下面这样的;要么是弹出一个model,在里面进行编辑保存操作

image.png

随着时代的发展,用户体验也越来越严格,优化为这样子↓↓↓

  • 默认显示表单value文字 image.png

  • 鼠标移入显示hover编辑样式

image.png

  • 鼠标点击,触发input焦点

image.png

  • 失去焦点,正则验证,保存数据,切换为文字样式

image.png


父组件

  • 引入,控制表单提交事件,子组件更新表单的值后,发送给父组件,提交数据即可
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;
}

客官记得点个赞哦😯😯😯!!!如有问题,欢迎评论区指正