功能描述
全选的功能应该大家都知道
以月份举例,点击全选,所有月份都被选择,再次点击全选,所有月份被取消选择;当所有月份都选上时,全选按钮会自动被勾选上,当月份不被全选时,全选按钮会不被勾选。
在此之前,全选的checkbox和月份的checkbox无任何关系
实现过程自己遇到的难点:
不知道该如何操控每个月份的checked属性,如何实现点击全选,操控所有月份checked = true
解决思路:
在月份数组给每个月份都设置单独的checked属性值操控
详情看代码
一、从后台拿到checkboxitem数组
(此处自己手写一个数组来假设使用)
const data = [
{ value: 1, label: '一月' },
{ value: 2, label: '二月' },
{ value: 3, label: '三月' },
{ value: 4, label: '四月' },
{ value: 5, label: '五月' },
{ value: 6, label: '六月' },
{ value: 7, label: '七月' },
{ value: 8, label: '八月' },
{ value: 9, label: '九月' },
{ value: 10, label: '十月' },
{ value: 11, label: '十一月' },
{ value: 12, label: '十二月' },
];
二、添加state数据
this.state = {
month:[],//保存所有选中的月份
isAllChecked:false,//全选按钮
allMonth:[]//添加了月份单独checked属性的数组
};
三、添加给每个月份添加checked属性的数组allMonth
componentDidMount(){
const arr = data;
arr.map(item => {
item.checked = false;
})
this.setState({
allMonth:arr
})
}
最后设置的allMonth数组是这样的,可以清楚看到,每个月份都有了一个单独的checked属性
注:但是此处会有一个缺陷
因为后台传过来的月份是没有属性check的,所以我们只能在state处创建一个数组,用来保存月份,并且手动给每个月份添加一个check。
而这个创建月份新数组的过程现在是在生命周期componentDidMount中实现的,但是在这个生命周期里写setState貌似不太好。会导致组件再次render,导致性能差。
但是如果放在componentWillMount也不行,因为这里的月份数组是需要通过后台接口拿到数据的,放在componentWillMonut可能会导致没有拿到数据,无法显示月份。
四、把全选和月份遍历显示出来
render(){
const {isAllChecked, allMonth} = this.state;
return(
<List renderHeader={() => '月份测试'}>
<Checkbox
onChange={(e)=>{this.allCheckMonth(e)}}
checked={isAllChecked}
>
全选
</Checkbox>
<Row>
{allMonth.map((item,index) => (
<Col span={8} key={item.value}>
<Checkbox.CheckboxItem
checked={item.checked}
onChange={(e)=>{this.addMonth(e,index)}}
>
{item.label}
</Checkbox.CheckboxItem>
</Col>
))}
</Row>
</List>
)
}
五、点击月份事件
addMonth = (e,index) =>{
const { allMonth } = this.state;
const newAllMonth = JSON.parse(JSON.stringify(allMonth));
const monthChecked = e.target.checked;//获取月份的点击状态
// 修改月份的选中状态
newAllMonth[index].checked = monthChecked;
// 保存已选中月份
const checkedMonth = [];
newAllMonth.map((item) => {
if (item.checked){
checkedMonth.push(item.value);
}
});
//把checked值改变了的新数组、保存了选中月份的数组month、是否所有月份被选中对应的数据在state处修改
//month是用于传给后台选中的数据,若不需要传数据,可不设置
this.setState({
allMonth: newAllMonth,
month: checkedMonth,
isAllChecked: checkedMonth.length === allMonth.length
});
};
六、点击全选事件
allCheckMonth = (e) =>{
const idChecked = e.target.checked;
const { allMonth } = this.state;
const newAllMonth = JSON.parse(JSON.stringify(allMonth));
//当用户点击全选,需把所有月份改成与全选相同的checked状态
newAllMonth.map((item) => {
item.checked = idChecked;
});
this.setState({
isAllChecked: idChecked,
allMonth: newAllMonth
});
};
over
笔者只是个前端小菜鸟,刚接触react不久,代码可能有缺陷,如果后期想到什么优化的方法也会补充上来,如果有啥问题缺陷,欢迎大家多多指教~