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')
)