By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account wrapperCol = { { span : 12 } } hasFeedback > < Input type = "email" placeholder = "onBlur 与 onChange 相结合" { ... getFieldProps ( 'email' , { validate : [ { rules : [ { required : true } , trigger : 'onBlur' , } , { rules : [ { type : 'email' , message : '请输入正确的邮箱地址' } , trigger : [ 'onBlur' , 'onChange' ] , } ) } / > < / FormItem >

存在问题是

  • 干扰组件的分类和层级关系
    这个demo里面,首先是校验代码远远大于组件本身,尤其多个表单项使用时候,整体表单会很庞杂,弱化了react组件使用本身应该体现组件的分类和层级关系, 从美观和使用上都不太顺手。
  • 配置项太重,喧宾夺主
    react配置项一般都比较轻,使用是,组件读取属性,进行处理,而这个demo是,首先注入了表单name,然后函数返回一个对象,再把对象属性值展开,放到props,而且都是外部完成的,感觉有点违背react的设计,react好像大多是组件本身具备行为,而不是通过外部函数辅助行为。而表单其实最重要的是字段,也不容易看清有哪些字段,校验有点喧宾夺主。
  • 这个createForm也看起来奇怪, 感觉不太符合react的设计,觉得react设计思路上,组件封装了行为,暴露到外面的函数一般是比较少的,一般使用都是找组件使用,而不是找函数使用。
  • const createForm = Form.create;
    Demo = createForm()(Demo); // 函数执行返回函数再执行,感觉也不透明
  • 简单的校验配置
    以前很多类似校验,也是元素上配置校验声明,但都会很简单,类似这样,整体表单会看起来清晰很多,至少一眼能看清表单本身有哪些字段
  • <input type="text" name="user" verify={users,required,minlen(3)]}>
    
  • 校验可以考虑高阶组件,在不影响表单结构的情况下,用校验组件包装表单项处理
  • redux-form 的 demo,react这部分结构就比较清晰,基本看上去还是简洁的表单。
    校验和表单分离是有好处的,一般表单项可能最关心是字段name,其次才是辅助的校验

    http://erikras.github.io/redux-form/#/examples/asynchronous-blur-validation?_k=zdaqvx

    <input type="text" placeholder="Username" {...username}/>
    
    <Input type="email" placeholder="onBlur 与 onChange 相结合"
                {...getFieldProps('email', {
                  validate: [{
                    rules: [
                      { required: true },
                    trigger: 'onBlur',
                    rules: [
                      { type: 'email', message: '请输入正确的邮箱地址' },
                    trigger: ['onBlur', 'onChange'],
              

    @swindme 其实你提的 redux-form 和楼顶的例子,只不过是把 username users required 等的定义放到了别处:

    <input type="text" placeholder="Username" {...username}/>
    <input type="text" name="user" verify={users,required,minlen(3)]}>

    antd 中也可以用变量把 getFieldProps 的返回值存起来再用

    const emailProps = getFieldProps('email', {
      validate: [{
        rules: [
          { required: true },
        trigger: 'onBlur',
      }, {
        rules: [
          { type: 'email', message: '请输入正确的邮箱地址' },
        trigger: ['onBlur', 'onChange'],
    });
    // JSX 部份就简单了
    <Input {...emailProps} type="email" placeholder="onBlur 与 onChange 相结合"/>

    然后 Form.create 就是使用了高阶组件啊。。不过是包装整个表单,而非单个表单域。这样的好处是把数据收集功能也一并做了,如果只是包装单个表单域的话,数据收集就要额外的代码了,之前的版本 就是这样。

  • 表单项校验内容清晰(这块 verify="users,required" 这种是直观的)
  • 当然更明确体现表单校验内容更好,之前的校验规则确实清晰,但是太庞杂了。以8个之前demo的input为例,本来8行就能看全的,配置了校验后,要112行才能看到这个表单到底传了哪些值。
    比如这样呢,很像原生的表单项,要增加校验,就注入校验到props,扩展和配置都比较清晰简洁, 反正最后也要Form.create搜集信息,这样写name感觉也能做吧?

    <input type="text" name="user" {...validate(username,required)}>
    

    或着用封装后的Input,内部支持校验规则的处理,如果有validate 属性,就开启校验,读取配置的一些校验规则:

    <Input type="text" name="user" validate={[username,required]}>
    

    Form.create 就是使用了高阶组件啊。。不过是包装整个表单,而非单个表单域。这样的好处是把数据收集功能也一并做了

    ok,这个场景理解了,多谢解答~

    我觉得作为一个业务系统的前端组件库, 根本不需要做表单验证啊..

    前端进行的表单验证到了后端还得再跑一遍, 你这边封装的再好, 后端都要重新实现一遍, 维护难度太大, 真用起来的时候,
    肯定是结合自己的后端或者API gateway框架, 封装一层类似于Django的From来用.

    Reply to this email directly or view it on GitHub
    #1024 (comment)

    @swindme 真心觉得这只是一个编程技巧的问题

    <input type="text" name="user" {...validate(username,required)}>
    <input {...getFieldProps('user', {rules: [ username, required ]})} type="text" />

    @benjycui 上面这种确实可以, 这个写法一行能读懂,能接受:

    <input {...getFieldProps('user', {rules: [ username, required ]})} type="text" />
    

    还有个办法是 这种看起来比较像原生,在react props方面会透明很多,不hack props。会不会好些

    <Input type="text" name="user" validate={[username,required]}>
              

    看了 : 这个代码demo
    大家觉得 庞杂的校验配置,感觉更影响阅读 , 那么可以抽离一个配置项文件, 把:

    export const passProps = getFieldProps('pass', {
      rules: [
        { required: true, whitespace: true, message: '请填写密码' },
        { validator: this.checkPass },
    });
    

    放在单独文件里面,在使用的时候 import 不就好了?这样维护也好,使用也简洁了。