antd+vue:tree component: The parent node prohibits selection and does not display the selection box - basic accumulation


Recently, when I was writing a backend management system, I encountered a need: permission management. Generally, permission management is divided into different levels according to functional classification.

The renderings are as follows:

Insert image description here
Today, the backend raised a requirement, as follows: no matter which layer of parent node it is, the selection box will not be displayed, but will only be displayed as a folded item.

Original words:这一层权限能改成不需要勾选么?就当个分组用
Insert image description here
The final rendering is as follows:
Insert image description here
Solution:

1. Determine which are the parent nodes and add disabled attribute to the parent node - this.permissionList is the data source

Determine whether it is a parent node through recursion.

filterMenuList(arr, item) {
    
    
  arr.forEach((child) => {
    
    
    if (child.children && child.children.length > 0) {
    
    
      child.disabled = true;
      child = this.filterMenuList(child.children, item);
    }
  });
  return item;
},

Use recursive method:

this.permissionList.forEach((item) => {
    
    
  if (item.permissions && item.permissions.length > 0) {
    
    
    item = this.filterMenuList(item.permissions, item);
  }
});

Through the above method, you can add the attribute disabled to the parent node as true.
Insert image description here

2. Process the parent node of disabled through css style

/deep/li.ant-tree-treenode-disabled
  > span.ant-tree-checkbox.ant-tree-checkbox-disabled {
    
    
  display: none !important;
}
/deep/
  .ant-tree
  li.ant-tree-treenode-disabled
  > .ant-tree-node-content-wrapper
  > span {
    
    
  color: rgba(0, 0, 0, 0.65) !important;
}

3. The complete code is as follows:

<template>
  <a-modal
    title="编辑API权限"
    :visible.sync="visible"
    :width="800"
    :maskClosable="true"
    @cancel="handleClose"
    @ok="handleSubmit"
  >
    <div id="topId"></div>
    <a-tabs tab-position="left">
      <a-tab-pane
        forceRender
        v-for="(group, index) in permissionList"
        :key="index + 1"
        :tab="group.displayName"
      >
        <a-tree
          ref="permissionTree"
          v-model="group.value"
          checkable
          checkStrictly
          :defaultExpandAll="true"
          :treeData="group.permissions"
          :replaceFields="replaceFields"
          @check="onCheck($event, group)"
        >
        </a-tree>
      </a-tab-pane>
    </a-tabs>
  </a-modal>
</template>
<script>
import {
    
     putApiPermission } from '@/services/menu';
export default {
    
    
  name: 'addPermissionList',
  components: {
    
    },
  data() {
    
    
    return {
    
    
      visible: false,
      loadLoading: false,
      permissionList: [],
      id: undefined,
      replaceFields: {
    
    
        value: 'permissionName',
        title: 'displayName',
        children: 'children',
        key: 'permissionName',
      },
      menuRoteIds: [],
    };
  },
  methods: {
    
    
    onCheck(obj, item) {
    
    
      item.value = obj.checked || [];
      this.$forceUpdate();
    },
    handleShow(row, permissionList) {
    
    
      this.visible = true;
      this.id = row.id;
      this.permissionList = [...permissionList];
      this.menuRoteIds = [...row.permissionNames];
      this.permissionList.forEach((item) => {
    
    
        item.value = [];
        if (this.menuRoteIds.includes(item.groupName)) {
    
    
          item.value.push(item.groupName);
        }
        if (item.permissions && item.permissions.length > 0) {
    
    
          item = this.filterMenuList(item.permissions, item);
        }
      });
      this.$nextTick(() => {
    
    
        document.getElementById('topId').scrollIntoView(true);
      });
    },
    filterMenuList(arr, item) {
    
    
      arr.forEach((child) => {
    
    
        if (this.menuRoteIds.includes(child.permissionName)) {
    
    
          item.value.push(child.permissionName);
        }
        if (child.children && child.children.length > 0) {
    
    
          child.disabled = true;
          child = this.filterMenuList(child.children, item);
        }
      });
      return item;
    },
    handleClose() {
    
    
      this.visible = false;
    },
    handleSubmit() {
    
    
      let arr = [];
      this.permissionList &&
        this.permissionList.forEach((item) => {
    
    
          arr = arr.concat(item.value);
        });
      let params = {
    
    
        permissionNames: arr || [],
      };
      this.loadLoading = true;
      putApiPermission(this.id, params)
        .then(() => {
    
    
          this.$message.success('保存成功');
          this.$emit('ok');
          this.handleClose();
        })
        .finally(() => {
    
    
          this.loadLoading = false;
        });
    },
  },
};
</script>
<style scoped>
/deep/.ant-modal-body {
    
    
  height: 500px;
  overflow-y: auto;
}
/deep/li.ant-tree-treenode-disabled
  > span.ant-tree-checkbox.ant-tree-checkbox-disabled {
    
    
  display: none !important;
}

/deep/
  .ant-tree
  li.ant-tree-treenode-disabled
  > .ant-tree-node-content-wrapper
  > span {
    
    
  color: rgba(0, 0, 0, 0.65) !important;
}
</style>

Guess you like

Origin blog.csdn.net/yehaocheng520/article/details/135018723