通过观察示例图,不难确认我们需要一个判断选择状态(全选/半选)checkStatus的方法,是否选中的onChange方法,以及是否全选的onCheckAllChange方法;
示例图:
代码逻辑
/**全选/半选列表 */
//已选中的列表
const [checkedList, setCheckedList] = useState<string[]>([])
//选择状态checkStatus的方法
const checkStatus = useMemo(() => {
let indeterminate = false//半选状态
let checkAll = false//全选状态
//未选
if (checkedList?.length === 0) {
indeterminate = false
checkAll = false
}
//全选
else if (checkedList?.length === fileData?.length) {
indeterminate = false
checkAll = true
} else {
//半选
indeterminate = true
checkAll = false
}
return {
indeterminate,
checkAll
}
}, [checkedList, fileData])
//是否选中onChange方法
const onChange = (checked: boolean, id: string) => {
if (checked) {
setCheckedList(pre => [...pre, id])
} else {
setCheckedList(pre => {
const cpPre = [...pre]
const opIndex = cpPre.findIndex(item => item === id)
if (opIndex === -1) return pre
cpPre.splice(opIndex, 1)
return cpPre
})
}
}
//全选onCheckAllChange方法
const onCheckAllChange = (checked: boolean) => {
if (checked) {
setCheckedList(fileData?.map(({id}) => id))
} else {
setCheckedList([])
}
}
DOM结构:
<div className="lists">
<div className="lists_checkAll">
<M_Checkbox
indeterminate={checkStatus.indeterminate}
onChange={({target: {checked}}) => {
onCheckAllChange(checked)
}}
checked={checkStatus.checkAll}
>
{`全选(已选择${checkedList.length ?? 0}个对象)`}
</M_Checkbox>
</div>
<div className="lists_item">
{fileData?.map(item => (
<FileItem
key={'file_' + item.id}
data={item}
onChange={onChange}
checkedList={checkedList}
/>
))}
</div>
</div>
<FileItem/>模块
<div className="File_check">
<M_Checkbox
checked={checkedList.includes(data.id)}
onChange={({target: {checked}}) => {
onChange(checked, data.id)
}}
/>
</div>