antd CheckBox实现全选、多选

antd CheckBox实现全选、多选

  1. 效果演示:

 

 

  1. 说明

    antd 组件库中的CheckBox有全选的效果可配置,但是当checkbox.group的item是遍历出来时,就不能直接实现全选效果

  1. 实现思路

    配合状态管理StateManage的使用,实时改变dataSource。此处卡片中使用的是单个CheckBox,而不是CheckBox.Group。

    • 当点击【全选】CheckBox时,如果checked为true,则往Set对象checkedListSet中添加dataSource的所有item。并且给dataSource中每个item都添加checked属性,值为true。

    • 然后将map返回的dataSource(已添加checked属性) set 到状态管理中 ,setCheckAll(e.target.checked)控制当前是否全选。

    • item中checkedbox的checked状态由dataSource遍历获得,当某个item触发onChange时,先修改dataSource. item中的checked状态,然后在状态管理中更新dataSource, 确保每个item的checked状态都与dataSource中的一致。

    • 获取当前勾选的item,遍历dataSource,然后add到Set对象checkedListSet中

     

  1. 关键代码

    --逻辑处理部分代码---------------------------------------  
    // 单个CheckBox
     const onChange = () => {
       dataSource.map(item => {
         item.checked ? checkedListSet.add(item.id) : null;
         setCheckedIds([...checkedListSet]);
      });
       setIndeterminate(
         !!checkedListSet.size && checkedListSet.size < dataSource.length
      );
       setCheckAll(checkedListSet.size === dataSource.length);
    };

     // 全选
     const onCheckAllChange = e => {
       dataSource.map(item => {
         !!e.target.checked && checkedListSet.add(item.id);
         setCheckedIds([...checkedListSet]);
         return (item.checked = e.target.checked);
      });
       StateManage.set(manual_controlKey, { dataSource: dataSource });
       setIndeterminate(false);
       setCheckAll(e.target.checked);
    };

    -- JSX 部分代码 -------------------------------------------------
    <div
             style={{
               display: "flex",
               justifyContent: "space-between",
               alignItems: "center"
            }}
           >
             <Checkbox
               indeterminate={indeterminate}
               onChange={onCheckAllChange}
               checked={checkAll}
             >
               全选
             </Checkbox>
             <DeleteBtn />
           </div>
           <hr style={{ margin: "5px 0" }} />
           <div style={{ display: "flex", justifyContent: "start" }}>
             <Row
               gutter={20}
               style={{
                 maxHeight: document.body.clientHeight - 200 + "px",
                 width: document.body.clientWidth - 60 + "px"
              }}
             >
              {dataSource ? (
                 orderBy(dataSource, ["snapTime"], ["DESC"]).map((item, index) => {
                   return (
                     <Col span={4}>
                       <Card
                         title={
                           // -------------- 关键代码 ------------------------
                           <Checkbox
                             key={index}
                             checked={dataSource[index].checked}
                             onChange={e => {
                               dataSource[index].checked = e.target.checked;
                               StateManage.set(manual_controlKey, {
                                 dataSource: dataSource
                              });
                               onChange();
                            }}
                             onClick={e => {
                               e.stopPropagation();
                            }}
                           />
                        }
                         // 此处省略卡片头部右侧【更多】的代码
                         hoverable
                         style={{ marginBottom: "10px", padding: "2px" }}
                         cover={<img alt="example" src={item.picURL} />}
                       >
                         <Meta description={item.channel_name + item.catch_time} />
                       </Card>
                     </Col>
                  );
                })
              ) : (
                 <div style={{ padding: "20px", width: "100%" }}>
                   <Empty description="暂无数据" />
                 </div>
              )}
             </Row>
           </div>
     
posted @ 2022-05-19 23:42  Freakzzz  阅读(4854)  评论(0编辑  收藏  举报