当前位置:   article > 正文

react模仿ant-design的表单Form和Form.Item一会Form.Item的内容填充功能_react form.item

react form.item

1. 假如是登录页面,包含姓名和密码,新建Login.jsx

import React from 'react';
import Form from './Form';

export default class Login extends React.Component{
    constructor() {
        super();
        this.state = {
            Form : {
                model : {
                    name : '',
                    password : '',
                },
                rules : {
                    name : {require :true,message:'请输入姓名'},
                    password : {require :true , min : 6,message:'请输入密码'},
                },
            }
        };
        this.formRef = null;
    }
    submit =()=> {
        const model = this.formRef.getFormData();
        const validateResult = this.formRef.validate();
        // console.log('model' , model)
        //这里可以根据form的抛出验证方法验证填写字段
    };
    render() {
        return (
            <Form onRef={ref=>this.formRef=ref} className={'form'} model={this.state.Form.model} rules={this.state.Form.rules}>
                <Form.Item rule={{require :true,message:'请输入姓名5555'}} name={'name'} label="姓名" isItem={true}>
                    <input type="text" style={{marginLeft : "20px"}} placeholder="请输入姓名"/>
                </Form.Item>
                <Form.Item name={"password"} label="密码" isItem={true}>
                    <input type="password" placeholder="请输入密码"/>
                </Form.Item>
                <div>
                    <button type="button" onClick={this.submit}>提交</button>
                </div>
            </Form>
        );
    }
}



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

2. 写Form组件,新建Form.jsx

/**
 *为了实现数据绑定,感觉Form.Item里面的内容,在这里是完全拦截,用
 const children = this.props.children;
 const Elements = []; //formItem里面的内容
 React.Children.map(children, (child, i) => {
      const name = child.type.name ? child.type.name.toLowerCase() :child.type.toLowerCase();
        Elements.push({
          name : name,
          props : child.props
     })
});
 */

import React from 'react';
import styles from './Form.module.less';
import FormItem from "./FormItem";
import {deepClone} from '../../../util'
let thizForm; //等于class Form,可以在static Item里面调用功能了

class Form extends React.Component{
    constructor(props) {
        super(props);
        const state = {
            model: {},
            rules: {},
            validateErrors : {},
        };
        for(let name in props.model){
            state.validateErrors[name] = false;
        }
        this.state = state;
        this.ref = React.createRef();
        thizForm = this;
    }
    validate =()=> {
        //验证功能
        const model = this.props.model;
        const rules = this.props.rules;
        let validateErrors = deepClone(this.state.validateErrors);
        for(let name in validateErrors){
            validateErrors[name] = true;
            if(rules[name].require){

            }
        }
        this.setState({
            validateErrors : validateErrors,
        });
    };
    componentWillMount(){
        //传递ref到父级页面
        if(this.props.onRef){
            this.props.onRef(this)
        }
        //把props里面的数据,绑定到Form-class -> state里面,未做深拷贝,懒得写了
        const props = deepClone( this.props);
        const rules = props.rules;
        //formItem可能有自己的rule
        React.Children.map(props.children, (child,i) => {
            const childProps = child.props;
            if(childProps.hasOwnProperty('rule')){
                rules[childProps.name] = childProps.rule;
            }
        });
        this.setState({
            rules : rules,
            model: props.model,
        });
    }
    getFormData(){
        return this.state.model;
    }
    render() {
        //拦截Form里面的内容,在这里做传入Form.props的参数进去,为了实现数据绑定
        let newChildrens = [];
        React.Children.map(this.props.children, (child,i) => {
            let newChild = child;
            if(child.props.isItem){
                newChild = React.cloneElement(newChild, {
                    showValidateError : this.state.validateErrors[child.props.name] || false,//是否展示每个信息下边的提示信息
                    model : this.props.model,
                    ...child.props,
                    rule : this.state.rules[child.props.name],
                });
            }
            newChildrens.push(
                <React.Fragment key={i}>{newChild}</React.Fragment>
            );
        });
        if(newChildrens.length === 1){
            newChildrens = newChildrens[0]
        }
        return (
            <form className={styles.form}>
                {/*{this.props.children}*/}
                {newChildrens}
            </form>
        );
    }
    //Form.Item的组件方法
    static Item = class extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                showValidateError : false,
            };
        }
        onChange =(name , value)=>{
            //只是写了input的对应方法
            const model = thizForm.state.model;
            model[name] = value;
            thizForm.setState({
                model : model
            });
        };
        static getDerivedStateFromProps(props, state) {
            if (props.showValidateError !== state.showValidateError) {
                let { showValidateError } = props;
                return {
                    showValidateError, //把父组件最新的props.type重新赋值到 子组件state.type
                };
            }
            // 父组件的值没有变化,这里不做任何操作。
            return null;
        }
        render() {
            const children = this.props.children;
            const Elements = []; //里面的表单
            //拦截children,传入Form-props给的name字段,onChange的时候,能根据name对应的修改Form->state->model->[name]的值
            React.Children.map(children, (child, i) => {
                const name = child.type.name || child.type;
                Elements.push({
                    name : name.toLowerCase(),
                    props : child.props
                })
            });
            return (
                <FormItem {...this.props} showValidateError={this.state.showValidateError}>
                   {
                       Elements.map((Item , index) => {
                           return <div key={index}>
                               <Item.name {...Item.props} key={index} onChange={e => this.onChange(this.props.name , e.target.value)}/>
                               {
                                   this.state.showValidateError ? <p className={styles.errorMessage}>{this.props.rule.message}</p> : null
                               }
                           </div>
                       })
                   }
                </FormItem>
            );
        }
    };
}
export default Form;



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157

3. 编写FormItem组件,新建FormItem.jsx

import React from 'react';
import styles from './Form.module.less'

export default class FormItem extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            showValidateError : props.showValidateError,
        };
    }
    // componentDidUpdate(prevProps, prevState, snapshot) {
    //     console.log('prevProps' , prevProps)
    // }
    render() {
        return (
            <label htmlFor={this.props.key} className={styles.formItemContent}>
                <span className={'label'}>{this.props.label}</span>
                {this.props.children}
            </label>
        );
    }
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

- 查看结果

在这里插入图片描述

输入的时候,查看Form.state,已经录入了。

在这里插入图片描述
验证功能

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号