菜单/页面权限我们用menu表示,按钮权限用button表示

需求:

        1.选中/取消子级(button,也就是按钮级别),父级不关联 取消,但关联 选中

        2.选中/取消父级(menu),子级全部选中/取消

html部分

   <el-form-item label="页面权限" prop="name">
          <el-tree
            ref="treeRef"
            :data="data"
            node-key="id"
            show-checkbox
            default-expand-all
            check-strictly
            @check-change="handleCheckChange"
            @check="handleCheck"
          />
   </el-form-item>

data 数据部分

const treeRef = ref();

interface Tree {
  label: string;
  id: number;
  permissionType: number;
  children?: Tree[];
}

const data: Tree[] = [
  {
    label: "组织架构",
    id: 1,
    permissionType: 1,
    children: [
      {
        label: "成员管理",
        id: 2,
        permissionType: 1,

        children: [
          {
            label: "新增",
            id: 3,
            permissionType: 2
          },
          {
            label: "编辑",
            id: 4,
            permissionType: 2
          },
          {
            label: "删除",
            id: 5,
            permissionType: 2
          }
        ]
      },
      {
        label: "部门管理",
        id: 10,
        permissionType: 1,

        children: [
          {
            label: "新增",
            id: 11,
            permissionType: 2
          },
          {
            label: "编辑",
            id: 12,
            permissionType: 2
          },
          {
            label: "删除",
            id: 13,
            permissionType: 2
          }
        ]
      }
    ]
  }
];

具体方法部分



// 主要针对父级选中状态,对子级的影响
const handleCheck = (data: any, node: any) => {
  // 获取当前节点是否被选中
  const isChecked = treeRef.value!.getNode(data).checked;
  // 如果当前节点被选中,则遍历下级子节点并选中,如果当前节点取消选中,则遍历下级节点并取消
  if (isChecked) {
    // 判断该节点是否有下级节点,如果有那么遍历设置下级节点为选中
    data.children &&
      data.children.length > 0 &&
      setChildreChecked(data.children, true);
  } else {
    // 如果当前节点取消选中,则取消该节点下的子节点选中
    data.children?.length > 0 && setChildreChecked(data.children, false);
  }

  function setChildreChecked(node: any, isChecked: boolean) {
    node.forEach((item: any) => {
      item.children?.length > 0 && setChildreChecked(item.children, isChecked);
      // 修改勾选状态
      treeRef.value.setChecked(item.id, isChecked, false);
    });
  }
};
// 子级勾选状态对父级的影响
const handleCheckChange = (
  data: Tree,
  checked: boolean,
  indeterminate: boolean
) => {
  // 选中全部子节点,父节点也默认选中,但是子节点再次取消勾选或者全部子节点取消勾选也不会影响父节点勾选状态
  let checkNode = treeRef.value.getNode(data); //获取当前节点

  // 勾选部分子节点,父节点也默认选中
  if (checkNode.parent?.childNodes.some(e => e.checked)) {
    // 我这里给的是全选的显示,如果你需要半选的方式,请启用第二行代码
    checkNode.parent.setChecked(true, false);
    // 半选形式
    // checkNode.parent.indeterminate = true;
  }
  // 勾选全部子节点,父节点变为全选状态
  if (checkNode.parent?.childNodes.every(ele => ele.checked)
  ) {
    checkNode.parent.checked = true;
    // 半选形式(如果需要,则直接取消注释,无需注释上行代码)
    // checkNode.parent.indeterminate = false;
  }
  // 如果取消所有第二节点的勾选状态,则第一层父节点也取消勾选
  if (
    // 这里我自己给了 permissionType 属性 来判断是页面/侧边栏权限(permissionType 为1)还是按钮权限(permissionType 为2)
    checkNode.data.permissionType == 1 &&
    // checkNode.level == 2
    checkNode.parent.childNodes.every(ele => !ele.checked)
  ) {
    checkNode.parent.checked = false;
    // 半选形式(如果需要,则直接取消注释,无需注释上行代码)
    // checkNode.parent.indeterminate = false;
  }
};

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐