React三層多選框聯動/三級複選框聯動實現方法 (Vue同理數據驅動思想)

 靜態效果圖:

動態效果圖:

代碼(安裝ant design就可以跑了):

import { Checkbox, Collapse } from 'antd';
import React, { PureComponent } from 'react';

//假設這是後端返回的數據
const params = {
  "authTree": [
    {
      "authName": "商場數據分析",
      "authId": 1,
      "children": [{
        "authName": "數據概覽",
        "authId": 3,
        "children": [
          { "authName": "今日客流", "authId": 6 },
          { "authName": "整體趨勢", "authId": 7 }
        ]
      },
      {
        "authName": "數據概覽2",
        "authId": 4,
        "children": [
          { "authName": "今日客流2", "authId": 8 },
          { "authName": "整體趨勢2", "authId": 9 }
        ]
      }]
    },
    {
      "authName": "商場數據分析2",
      "authId": 2,
      "children": [{
        "authName": "數據概覽3",
        "authId": 5,
        "children": [
          { "authName": "今日客流3", "authId": 10 },
          { "authName": "整體趨勢3", "authId": 11 }
        ]
      }]
    }
  ],
  "checkedList": [6, 7, 11]
}

class AuthoritySettingComponent extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      authTree: [],
      checkedList: [],
    };
    this.itemHandle = this.itemHandle.bind(this);
  }


  componentDidMount() {
    // 後端返回的數據,轉成前端要用的數據保存頁面使用
    const authTree = params.authTree;
    const checkedList = params.checkedList;
    this.setState({
      authTree,
      checkedList,
    }, () => {
      this.authTreeFun();
    });
  }

  // 轉成前端要用的數據
  authTreeFun() {
    const checkedList = this.state.checkedList;
    checkedList.forEach((item) => {
      this.itemHandle(item);
    });
  }

  // 代碼三級聯動核心就在這裏
  itemHandle(authId, checked = true) {
    const authTree = [...this.state.authTree];

    authTree.forEach((item1) => {
      if (item1.authId === authId) {
        item1.checked = checked;
        if (item1.children) {
          item1.children.forEach((item2) => {
            item2.checked = checked;
            if (item2.children) {
              item2.children.forEach((item3) => {
                item3.checked = checked;
              });
            }
          });
        }
      } else {
        // 反向思路: 保存子選項框的個數, 子選項選中就-1, 等於0說明都選中了, 父選項就勾上
        let temp1 = item1.children.length;
        item1.children.forEach((item2) => {
          if (item2.authId === authId) {
            item2.checked = checked;
            if (item2.children) {
              item2.children.forEach((item3) => {
                item3.checked = checked;
              });
            }
          } else {
            let temp2 = item2.children.length;
            item2.children.forEach((item3) => {
              if (item3.authId === authId) {
                item3.checked = checked;
              }
              item3.checked ? temp2 -= 1 : temp2;
            });
            temp2 === 0 ? item2.checked = true : item2.checked = false;
          }
          //  選中-1, 未選中不動
          item2.checked ? temp1 -= 1 : temp1;
        });
        //  長度是0, 父選項框就勾選
        temp1 === 0 ? item1.checked = true : item1.checked = false;
      }
    });

    this.setState({
      authTree,
    });
  }

  render() {
    const { Panel } = Collapse;
    const authTreeMap = this.state.authTree.map((item1) => (
      // Panel是手風琴
      <Panel
        key={item1.authId}
        header={(
          <span onClick={(e) => { e.stopPropagation(); }}>
            {/* 一級複選框(向下操控二級三級) */}
            <Checkbox
              name={item1.authId.toString()}
              checked={item1.checked}
              onClick={(e) => {
                this.itemHandle(parseInt(e.target.name), e.target.checked);
              }}
            >
              {item1.authName}
            </Checkbox>
          </span>
        )}
      >
        {/* 二級複選框(向下操控三級,向上聯動一級) */}
        {item1.children.map((item2) => (
          <div key={item2.authId}>
            <Checkbox
              name={item2.authId.toString()}
              checked={item2.checked}
              onClick={(e) => {
                this.itemHandle(parseInt(e.target.name), e.target.checked);
              }}
            >
              {item2.authName}
            </Checkbox>
            <span>|</span>
            {/* 三級複選框(向上聯動二級一級) */}
            {item2.children.map((item3) => (
              <Checkbox
                key={item3.authId}
                name={item3.authId.toString()}
                checked={item3.checked}
                onClick={(e) => {
                  this.itemHandle(parseInt(e.target.name), e.target.checked);
                }}
              >
                {item3.authName}
              </Checkbox>
            ))}
          </div>
        ))}
      </Panel>
    ));
    return (
      <div>
        <Collapse expandIconPosition="right">
          {authTreeMap}
        </Collapse>
      </div>
    );
  }
}

export default AuthoritySettingComponent;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章