index.vue 2.6 KB

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