index.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <template>
  2. <div class="custom-tree">
  3. <div v-for="item in nodeData" :key="item.value" class="custom-tree-children">
  4. <div class="custom-tree-item" @click.stop="toCurrentNode(item)">
  5. <!-- 没有子节点数据不显示箭头 -->
  6. <template v-if="item.children && item.children.length > 0">
  7. <span v-if="!expandedkeysArray.includes(item.value)">→</span>
  8. <span v-else>↓</span>
  9. </template>
  10. <span>{{ item.label }}</span>
  11. </div>
  12. <!-- children有值 && expandedkeysArray数组存在该value值时再展开显示 -->
  13. <transition name="expand">
  14. <custom-tree v-if="item.children && item.children.length > 0 && expandedkeysArray.includes(item.value)" :node-data="item.children" :style="{marginLeft: `${getLevel() * 20}px`}" />
  15. </transition>
  16. </div>
  17. </div>
  18. </template>
  19. <script>
  20. export default {
  21. name: 'custom-tree',
  22. props: {
  23. nodeData: {
  24. type: Array,
  25. default: () => ([])
  26. },
  27. expandedkeys: {
  28. type: Array,
  29. default: () => ([])
  30. },
  31. },
  32. computed: {
  33. // 实时更新父组件的值
  34. expandedkeysArray: {
  35. get() {
  36. return this.expandedkeys
  37. },
  38. set(newVal) {
  39. this.$emit('update:expandedkeys', newVal)
  40. }
  41. }
  42. },
  43. methods: {
  44. // 点击整行事件,向父组件返回当前节点和当前层级
  45. toCurrentNode(item) {
  46. const node = {
  47. ...item,
  48. level: this.getLevel()
  49. }
  50. this.$emit('currentNode', node)
  51. // 没有展开的子节点才push展开
  52. if (!this.expandedkeysArray.includes(item.value)) {
  53. this.expandedkeysArray.push(item.value)
  54. return
  55. }
  56. // 已经展开的子节点删除收起
  57. const index = this.expandedkeysArray.indexOf(item.value)
  58. if (index !== -1) {
  59. this.expandedkeysArray.splice(index, 1)
  60. }
  61. },
  62. // 根据父节点层数判断当前层级
  63. getLevel() {
  64. let level = 1;
  65. let parent = this.$parent;
  66. while (parent && parent.$options.name === 'custom-tree') {
  67. level++;
  68. parent = parent.$parent;
  69. }
  70. return level;
  71. }
  72. }
  73. };
  74. </script>
  75. <style lang="less" scoped>
  76. .custom-tree{
  77. .custom-tree-item{
  78. cursor: pointer;
  79. border-bottom: 1px solid #E4E7ED;
  80. display: flex;
  81. align-items: center;
  82. padding: 5px 10px;
  83. &:hover{
  84. background: #F2F6FC;
  85. }
  86. }
  87. }
  88. .expand-enter-active, .expand-leave-active {
  89. transition: all 0.3s;
  90. }
  91. .expand-enter, .expand-leave-to {
  92. transform: scaleY(0);
  93. transform-origin: top;
  94. opacity: 0;
  95. }
  96. </style>