<template>
  <div class="custom-tree">
    <div v-for="item in nodeData" :key="item.value" class="custom-tree-children">
      <div class="custom-tree-item" @click.stop="toCurrentNode(item)">
        <!-- 没有子节点数据不显示箭头 -->
        <template v-if="item.children && item.children.length > 0">
          <span v-if="!expandedkeysArray.includes(item.value)">→</span>
          <span v-else>↓</span>
        </template>
        <span>{{ item.label }}</span>
      </div>
      <!-- children有值 && expandedkeysArray数组存在该value值时再展开显示 -->
      <transition name="expand">
        <custom-tree v-if="item.children && item.children.length > 0 && expandedkeysArray.includes(item.value)" :node-data="item.children" :style="{marginLeft: `${getLevel() * 20}px`}" />
      </transition>
    </div>
  </div>
</template>
<script>
export default {
  name: 'custom-tree',
  props: {
    nodeData: {
      type: Array,
      default: () => ([])
    },
    expandedkeys: {
      type: Array,
      default: () => ([])
    },
  },
  computed: {
    // 实时更新父组件的值
    expandedkeysArray: {
      get() {
        return this.expandedkeys
      },
      set(newVal) {
        this.$emit('update:expandedkeys', newVal)
      }
    }
  },
  methods: {
    // 点击整行事件，向父组件返回当前节点和当前层级
    toCurrentNode(item) {
      const node = {
        ...item,
        level: this.getLevel()
      }
      this.$emit('currentNode', node)
      // 没有展开的子节点才push展开
      if (!this.expandedkeysArray.includes(item.value)) {
        this.expandedkeysArray.push(item.value)
        return
      }
      // 已经展开的子节点删除收起
      const index = this.expandedkeysArray.indexOf(item.value)
      if (index !== -1) {
        this.expandedkeysArray.splice(index, 1)
      }
    },
    // 根据父节点层数判断当前层级
    getLevel() {
      let level = 1;
      let parent = this.$parent;
      while (parent && parent.$options.name === 'custom-tree') {
        level++;
        parent = parent.$parent;
      }
      return level;
    }
  }
};
</script>
<style lang="less" scoped>
.custom-tree{
  .custom-tree-item{
    cursor: pointer;
    border-bottom: 1px solid #E4E7ED;
    display: flex;
    align-items: center;
    padding: 5px 10px;
    &:hover{
      background: #F2F6FC;
    }
  }
}
.expand-enter-active, .expand-leave-active {
  transition: all 0.3s;
}
.expand-enter, .expand-leave-to {
  transform: scaleY(0);
  transform-origin: top;
  opacity: 0;
}
</style>