需求场景描述:
一个input A
一个input 列表B
现在要实现的就是当操作单个input A时
除了自己可以选中和非选中外,还要关联Input 列表B的全部选中和不选中
当然 操作input 列表B中的任意一项,也要关联单个Input A
我们来实现程序
App.js 引入模块
这路由还没引入
还是修改当前页面
import Input2 from './views/Input2';
<Input2/>
新建页面 Input2
vi src/views/Input2/index.jsx
第一步把html 结构实现了
<React.Fragment>
<h3>全选</h3>
<label>
<input type="checkbox"
/>
全选
</label>
<ul>
<li>
<label>
<input type="checkbox"
/>
内容一
</label>
</li>
<li>
<label>
<input type="checkbox"
/>
内容二
</label>
</li>
<li>
<label>
<input type="checkbox"
/>
内容三
</label>
</li>
</ul>
</React.Fragment>
ok 结构完了后,
回想一下我们需求
先定义一下数据结构
多个是数组 单个我们之前也提到过不要直接在state 根上
增加一个隶属关系
所以就有如下结构
this.state = {
bTrue:{
allSel:false,
},
mvc:[
{lang:'angular',checked:false},
{lang:'vue',checked:false},
{lang:'ember',checked:false},
{lang:'react',checked:false},
{lang:'omi',checked:false},
]
}
数据结构已定义,那我们把ul 内容给循环一下
<ul>{this.listFn(mvc)}</ul>
listFn(data){
return data.map((item,index)=>(
<li key={index}>
<label>
<input type="checkbox"
/>
{item.lang}
</label>
</li>
))
}
ok
这样结构就有了
继续我们给单个input 增加事件以及checked
let {bTrue,mvc} = this.state;
<input type="checkbox"
name='allSel'
checked={bTrue.allSel}
onChange={(e)=>{this.allSelFn(e)}}
/>
首页这个事件没问题吧
checked 也没问题吧
name 为字段内容
以此把多个input 内容也改一下
<li key={index}>
<label>
<input type="checkbox"
name='allSel'
checked={item.checked}
onChange={(e)=>{this._allSelFn(e,index)}}
/>
{item.lang}
</label>
</li>
为了能区分操作的是哪个事件所以我们把下标传过去了。
ok 这样我们就开始 写函数了
allSelFn(e){
let { name , checked } = e.target;
let {bTrue,mvc} = this.state;
bTrue[name] = checked;
this.setState({bTrue})
这样是不是单个input
}
那如何要操作单个关系多个是不就需要一个循环了
升级一下
allSelFn(e){
let { name , checked } = e.target;
let {bTrue,mvc} = this.state;
mvc.forEach((item, i) => {
if(checked){
item.checked = true;
}else {
item.checked = false;
}
});
this.setState({bTrue,mvc})
}
此,单个input 可以完全控制多个input 全选或不选
_allSelFn(e,index){
let { name , checked } = e.target;
let {bTrue,mvc} = this.state;
第按上面的同样实现本身切换
mvc[index].checked = checked;
this.setState({mvc})
这样每一项都可以全选中和不选中了
}
继续关联
_allSelFn(e,index){
let { name , checked } = e.target;
let {bTrue,mvc} = this.state;
第按上面的同样实现本身切换
mvc[index].checked = checked;
let bT = mvc.every((item,index)=>{
return item.checked;
})
bTrue[name] = bT;
this.setState({bTrue,mvc})
这样每一项都可以全选中和不选中了
}
这样一个全选和反选的就实现了,
完整代码
src/views/Input2/index.jsx
import React, { Component } from 'react';
class View extends Component {
constructor(props){
super(props);
this.state = {
bTrue:{
allSel:false,
},
mvc:[
{lang:'angular',checked:false},
{lang:'vue',checked:false},
{lang:'ember',checked:false},
{lang:'react',checked:false},
{lang:'omi',checked:false},
]
}
}
allSelFn(e){
let { name , checked } = e.target;
let {bTrue,mvc} = this.state;
bTrue[name] = checked;
mvc.forEach((item, i) => {
if(checked){
item.checked = true;
}else {
item.checked = false;
}
});
this.setState({bTrue,mvc})
}
_allSelFn(e,index){
let { name , checked } = e.target;
let {bTrue,mvc} = this.state;
mvc[index].checked = checked;
let bT = mvc.every((item,index)=>{
return item.checked;
})
bTrue[name] = bT;
this.setState({bTrue,mvc})
}
listFn(data){
return data.map((item,index)=>(
<li key={index}>
<label>
<input type="checkbox"
name='allSel'
checked={item.checked}
onChange={(e)=>{this._allSelFn(e,index)}}
/>
{item.lang}
</label>
</li>
))
}
render(){
let {bTrue,mvc} = this.state;
return(
<React.Fragment>
<h3>全选</h3>
<label>
<input type="checkbox"
name='allSel'
checked={bTrue.allSel}
onChange={(e)=>{this.allSelFn(e)}}
/>
全选
</label>
<ul>{this.listFn(mvc)}</ul>
</React.Fragment>
)
}
}
export default View;