js实现原生checked全选、半选、未选实现逻辑

105 阅读1分钟

通过观察示例图,不难确认我们需要一个判断选择状态(全选/半选)checkStatus的方法,是否选中的onChange方法,以及是否全选的onCheckAllChange方法;

示例图:

企业微信截图_17174067395630.png

企业微信截图_17174067504474.png

企业微信截图_17174067571368.png

代码逻辑

/**全选/半选列表 */ 

  //已选中的列表
  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 === -1return 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>