formily/core

593 阅读1分钟

介绍

处理数据的第三方

架构

Form:涉及表单,将所有的表单统一管理 Field:单独的input数据管理 reactive:数据更新通知组件

createForm

new Form()

Form

form里面有一个fields属性用来存储所有的field

    constructor(props){
        this.fields = {}
    }

createField 每次经过Field组件层的时候不可能调用一次createField就new一次Field数据层

  //根据foelds是否存在name对应的Field实例来判断是否new
  createField = (props) => {
    const { name } = props;
    if (!this.fields[name]) {
      new Field(name, props, this);
    }
    return this.fields[name]
  };

/*
Field
*/
  //new 的时候顺便挂载到fields上去
  export default class Field {
  constructor(name_, props_, form_) {
    this.form = form_;
    this.name = name_;
    this.props = {...props_}
    this.form.fields[name_] = this
  }
}

声明values,同时将input变为响应式

  constructor(props_) {
    //初始化
    this.initialize(props_)
    //响应式
    this.makeObservable()
  }

  makeObservable = () => {
    define(this,{
      fields:observable.shallow,
      values:observable,
    })
  }

  initialize = (props) => {
    this.props = {...props_}
    this.fields = {};
    //value初始化
    this.initialValues = props.initialValues
    //所有Field的value,要变成响应式
    this.values = {...props.initialValues}
  }

Field

将Field组件的属性挂在到Field对象上

export default class Field {
  constructor(name_, props_, form_) {
    this.props = {...props_}
    //挂载到fields上
    this.form = form_;
    this.name = name_;
    this.form.fields[name_] = this
    //这俩是Field组件层生成组件的参数
    this.component = props_.component
    this.decorator = props_.decorator
      //component组件下给input的value值,使input变成受控组件,从form上value上获取
    this.value = this.form.values[name_]
    //formItem组件下报错提示
    this.selfErrors = [] 
        //标题
    this.title = props_.title
        //校验
    this.query= {require:props_.require}
  }

  //component组件下给input的onChange事件
  onInput = (e) => {
    const newvalue = e.target.value;
  }
}

根据最新的newvalue来更新value

  onInput = (e) => {
    const newValue = e.target.value;
    console.log('newValue:',newValue);
    this.value = newValue
    this.form.values[this.name] = newValue
  }

field的value是根据form产生的因此要将Field变为响应式

  makeObservable = () => {
    define(this, {
      value: observable,
      selfErrors:observable,
    });
  };

internals

export const validateSelf = (field) => {
    const value = field.value

    if(typeof value == 'string'){
        value = value.trim()
    }

    const query = field.query
    if(query.require && (value == '' || validateSelf == undefined)){
        field.selfErrors = ['请输入必填项']
    }
}

input框同步(password)

export const createReactions = (field) => {
  const reactions = field.props.reactions;
  if (typeof reactions === "function") {
    autorun(
      batch.scope.bound(() => {
        reactions(field);
      })
    );
  }
};

提交+校验

export const batchValiDate = (form) => {
    //全部校验
    const errors = []

    for(let key in form.fields){
        const field = form.fields[key]
        validateSelf(field)
        if(field.selfErrors[0]){
            errors.push({key,msg:field.selfErrors[0]})
        }
        if(errors.length > 0){
            throw errors
        }
    }
}

export const batchSubmit = async (form,onSubmit) => {
    await batchValiDate(form)
    return onSubmit(toJS(form.values))
}