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;
发布了127 篇原创文章 · 获赞 150 · 访问量 48万+

猜你喜欢

转载自blog.csdn.net/qq_40259641/article/details/105594912
今日推荐