React 受控表单组件

React 受控表单组件

受控组件(Controlled Component):
组件的数据受到state组件状态的控制(组件的数据和state组件状态双向绑定)
在这里插入图片描述

const {Component,Fragment} = React;
//受控表单组件
class FormItem extends Component{
    constructor(props){
        super(props);
        this.state = {
            nick:'',    //绑定昵称文本框
            chars:0,    //已经输入的文本个数
            charFull:20,    //总共能输入20个
            msg:'', //绑定留言多行文本域
            workers:['教师','学生','军人','厨师','司机'],  //为职务单选框提供数据
            worker:'',  //绑定职务数据(取值为字符串)
            favs:['旅游','游戏','音乐','电影','读书','睡觉'],    //为爱好复选框提供数据
            fav:[], //为爱好绑定复选框(取值为数组)
            specs:['前端开发专业','PHP开发专业','Java开发专业','UI设计专业','软件工程专业'],    //为专业提供原始数据
            spec:'前端开发专业',    //为专业绑定数据
            courses:['HTML','CSS','jQuery','JavaScript','DOM','Vue.js','React.js'],
            course:['jQuery']
        }
    }
    //昵称的onChange事件
    nickChange(event){
        this.setState({
            nick:event.target.value
        })
    }
    //职务的onChange事件
    workerChange(event){
        this.setState({
            worker:event.target.value
        })
    }
    //爱好的onChange事件
    favChange(event){
        let temp = event.target.value;  //用户单选的那一项
        let fav = [...this.state.fav];
        let index = fav.findIndex(item=>item === temp);
        if(index !== -1){   //单击该复选框时,该复选框的value属性取值在fav数组中存在
            fav.splice(index,1);
        }else{  //单击该复选框时,该复选框的value属性取值在fav数组中不存在
            fav.push(temp);
        }
        this.setState({
            fav
        })

    }
    //专业的onChange事件
    specChange(event){
        this.setState({
            spec:event.target.value
        })
    }
    //选修的onChange事件
    courseChange(event){
        // //方案一:实现列表不需要借助快捷键就能通过单击鼠标完成选中或取消选中
        // let value = event.target.value;  //最后选中的哪一个列表项的value取值
        // let course = [...this.state.course];
        // let index = course.findIndex(item=>item===value);
        // //判断value值是否在course数组中出现过
        // if(index >= 0){
        //     course.splice(index,1)
        // }else{
        //     course.push(value)
        // }
        // this.setState({
        //     course
        // })

        // //方案二:实现列表借助快捷键(Ctrl、Shift)完成多选功能
        // let options = event.target.options;  //返回由所有的<option>标记组成的对象,对象的属性名:所以只(0,1,2,3,...),对象的属性值:<option>DOM节点
        // let temp = [];  //盛放被选中的options项的索引值的数组
        // for(let i in options){
        //     if(options[i].selected){
        //         temp.push(i)
        //     }
        // }
        // let course = temp.map(item=>options[item].value);
        // this.setState({
        //     course
        // })

        //方案三:(同方案二原理,简化版)
        let options = event.target.options;
        let course = Object.keys(options).filter(item=>options[item].selected === true).map(item=>options[item].value);
        this.setState({
            course
        })
    }
    //留言的onChange事件
    textareaChange(event){
        let temp = event.target.value.slice(0,this.state.charFull);
        this.setState({
            msg:temp,
            chars:temp.length
        })
    }
    //留言按钮的单击事件
    btnClick(){
        console.log(`昵称:${this.state.nick}`);
        console.log(`职务:${this.state.worker}`);
        console.log(`爱好:${this.state.fav}`);
        console.log(`专业:${this.state.spec}`);
        console.log(`选修:${this.state.course}`);
        console.log(`留言:${this.state.msg}`);
    }
    render(){
        return(
            <Fragment>
                <div className="container">
                    <div className="row">
                        <div className="col-md-12">
                            <h1>React受控表单元素组件</h1><hr/>
                        </div>
                        <div className="col-md-12">
                            <div className="form-group">
                                <label>昵称:</label>
                                <input type="text" value={this.state.nick} className="form-control" onChange={()=>this.nickChange(event)} />
                            </div>
                            <div className="form-group">
                                <label>职务:</label>
                                {
                                    this.state.workers.map((item,index)=>{
                                        return (
                                            <Fragment key={index}>
                                                <input type="radio"value={item} checked={this.state.worker == item} onChange={()=>this.workerChange(event)}
                                                style={{marginLeft:'10px'}}/>{item}
                                            </Fragment>
                                        )
                                    })
                                }
                            </div>
                            <div className="form-group">
                                <label>爱好:</label>
                                {
                                    this.state.favs.map((item,index)=>{
                                        return (
                                            <Fragment key={index}>
                                                <input type="checkbox" value={item} checked={this.state.fav.includes(item)} onChange={()=>this.favChange(event)}
                                                       style={{marginLeft:'10px'}} />{item}
                                            </Fragment>
                                        )
                                    })
                                }
                            </div>
                            <div className="form-group">
                                <label>专业:</label>
                                <select value={this.state.spec} onChange={()=>this.specChange(event)} className="form-control">
                                    {
                                        this.state.specs.map((item,index)=>{
                                            return (
                                                <option value={item} key={index}>{item}</option>
                                            )
                                        })
                                    }
                                </select>
                            </div>
                            <div className="form-group">
                                <label>选修:</label>
                                <select className="form-control" multiple size={this.state.courses.length} value={this.state.course} onChange={()=>this.courseChange(event)}>
                                    {
                                        this.state.courses.map((item,index)=>{
                                            return (
                                                <option value={item} key={index}>{item}</option>
                                            )
                                        })
                                    }
                                </select>
                            </div>
                            <div className="form-group">
                                <label>留言:(已输入:{this.state.chars}/{this.state.charFull}</label>
                                <textarea value={this.state.msg} rows="10" className="form-control" onChange={()=>this.textareaChange(event)}></textarea>
                            </div>
                            <div className="form-group">
                                <button className="btn btn-primary" onClick={()=>this.btnClick()}>提交留言</button>
                            </div>
                        </div>
                    </div>
                </div>
            </Fragment>
        )
    }
}

ReactDOM.render(
    <div>
        <FormItem></FormItem>
    </div>,
    document.getElementById('userForm')
)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值