index.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <template>
  2. <ul class="ui-tree" :style="style" :class="{ children: level > 1, stroke, flat: level > maxTab }">
  3. <template v-for="(item, index) in data" :key="item.id || index">
  4. <li
  5. class="ui-tree-item"
  6. :class="{
  7. alone: data.length === 1,
  8. put: animationsRef[index].value && !animationsRef[index].value.show,
  9. }"
  10. v-if="item.children && item.children.length"
  11. >
  12. <div class="ui-tree-content">
  13. <span :class="{ first: !index }" class="ui-tree-auxiliary" v-if="stroke && index !== item.children.lengt - 1"> </span>
  14. <span class="ui-tree-ctrl" :class="{ open: animationsRef[index]?.value?.show }" @click="animationsRef[index].value.changeShow()"> </span>
  15. <slot :row="item" :locals="[...locals, index]"></slot>
  16. </div>
  17. <UISizeAnimation animationStyle="scale" :ref="animationsRef[index]" class="ui-tree-item-child">
  18. <ui-tree :style="style" :stroke="stroke" :data="item.children" :max-tab="maxTab" :level="level + 1" :open="open" :locals="[...locals, index]">
  19. <template #default="slotData">
  20. <slot v-bind="slotData"></slot>
  21. </template>
  22. </ui-tree>
  23. </UISizeAnimation>
  24. </li>
  25. <li class="ui-tree-item un-children" v-else>
  26. <div class="ui-tree-content">
  27. <slot :row="item" :locals="[...locals, index]"></slot>
  28. </div>
  29. <div class="ui-tree-item-child" v-if="stroke"></div>
  30. </li>
  31. </template>
  32. </ul>
  33. </template>
  34. <script>
  35. export default { name: 'UiTree' }
  36. </script>
  37. <script setup>
  38. // computed
  39. import { defineProps, ref, watchEffect, defineExpose } from 'vue'
  40. import UISizeAnimation from '../size-animation'
  41. const props = defineProps({
  42. data: {
  43. type: Array,
  44. require: true,
  45. },
  46. locals: {
  47. type: Array,
  48. default: () => [],
  49. },
  50. level: {
  51. type: Number,
  52. default: 1,
  53. },
  54. maxTab: { type: Number },
  55. open: { type: Boolean },
  56. stroke: { type: Boolean },
  57. style: { type: [Object, String] },
  58. })
  59. const animationsRef = ref(props.data.map(item => ref(null)))
  60. const changeShowAll = isOpen => {
  61. for (let ranimationRef of animationsRef.value) {
  62. ranimationRef && ranimationRef.value?.changeShow(isOpen)
  63. }
  64. }
  65. watchEffect(() => changeShowAll(props.open))
  66. defineExpose({
  67. openAll: () => changeShowAll(true),
  68. closeAll: () => changeShowAll(false),
  69. })
  70. </script>