SysAppMenuTree.vue 4.37 KB
<template>
  <el-scrollbar class="fullheight">
    <ht-tree
      :data="treeData"
      :props="defaultProps"
      :support-filter="supportFilter"
      :highlight-current="highlightCurrent"
      :default-expand-all="defaultExpandAll"
      :default-expanded-keys="['-1', '1']"
      :default-checked-keys="defaultCheckedKeys"
      :node-key="nodeKey"
      :show-checkbox="showCheckbox"
      :render-content="renderContent"
      :expand-on-click-node="false"
      @node-click="handleNodeClick"
      @refresh="loadData(id)"
      draggable
      @node-drop="handleNodeDrop"
      :allow-drop="allowDrop"
      ref="htMenuTree"
    >
      <!-- 作用域插槽:插槽prop -->
      <slot slot-scope="{node, data}" :node="node" :data="data"></slot>
    </ht-tree>
  </el-scrollbar>
</template>

<script>
import portal from '@/api/portal'
import _ from 'lodash'
export default {
  name: 'sys-app-menu-tree',
  props: {
    supportFilter: {
      type: Boolean,
      default: false,
    },
    highlightCurrent: {
      type: Boolean,
      default: false,
    },
    defaultExpandAll: {
      type: Boolean,
      default: false,
    },
    showCheckbox: {
      type: Boolean,
      default: false,
    },
    renderContent: {
      type: Function,
    },
    defaultCheckedKeys: {
      type: Array,
    },
    nodeKey: {
      type: String,
      default: 'alias',
    },
    id: String,
  },
  data() {
    return {
      treeData: [],
      defaultProps: {
        children: 'children',
        label: 'name',
      },
    }
  },
  methods: {
    handleNodeClick(data, node) {
      this.$emit('node-click', data, node)
    },
    loadData(id, cb) {
      this.$store
        .dispatch('menu/getAppMenus', id)
        .then((data) => {
          let tempData = _.cloneDeep(data)
          function handleTreeData(data, limit = 3, count = 1) {
            return data.map((x) => ({
              ...x,
              children:
                count < limit
                  ? handleTreeData(x.children, limit, count + 1)
                  : [],
            }))
          }
          this.treeData = handleTreeData(tempData) || []
          this.$forceUpdate()
        })
        .finally(() => {
          cb && cb()
        })
    },
    load() {
      this.loadData(this.id)
    },
    allowDrop(draggingNode, dropNode, type) {
      if (type === 'inner') {
        if (dropNode.data.menuType === 'page') {
          console.info('page cant drop!')
          return false
        }
        if (dropNode.level > 2) {
          console.info('second folder cant drop!')
          return false
        }
        if (draggingNode.data.menuType === 'category' && dropNode.level > 1) {
          console.info('category cant drop to second folder!')
          return false
        }
      } else {
        if (draggingNode.data.menuType === 'category' && dropNode.level > 2) {
          console.info('category cant drop to second folder!')
          return false
        }
      }
      return true
    },
    handleNodeDrop(draggingNode, dropNode, dropType) {
      let parentId, children
      if (dropType === 'inner') {
        parentId = dropNode.data.id
        children = dropNode.data.children
      } else {
        parentId = dropNode.data.parentId
        children =
          dropNode.data.parentId !== '0'
            ? dropNode.parent.data.children
            : this.treeData
      }

      let menuIds = children.map((item) => item.id)
      portal.sortAppMenu({parentId, appId: this.id, menuIds}).then((resp) => {
        if (resp.data.state) {
          this.$emit('clearRightMeun')
          this.loadData(this.id)
        }
      })
    },
  },
  watch: {
    id: {
      handler(newVal, oldVal) {
        if (newVal && oldVal !== newVal) {
          // this.loadData(newVal)
        }
      },
      deep: true,
      immediate: true,
    },
  },
}
</script>

<style lang="scss" scoped>
>>> .el-tree .el-tree__empty-block {
  margin: 20px 20px;
  width: calc(100% - 40px);
}

>>> .el-tree {
  width: 100%;
}

>>> .el-scrollbar__wrap {
  overflow-x: hidden;
}

::v-deep {
  .el-tree--highlight-current
    .el-tree-node.is-current
    > .el-tree-node__content {
    background: #ebf5ff;
    color: #409eff;

    .el-dropdown,
    .drag {
      i {
        visibility: visible;
      }
    }

    .drag {
      i {
        visibility: visible;
        color: #333333;
      }

      i:hover {
        color: #409eff;
      }
    }
  }
}
</style>