CheckBoxTreeListItem.vue 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <template>
  2. <FlexCol>
  3. <FlexRow align="center" :gap="20">
  4. <IconButton
  5. v-if="item.hasChildren !== false"
  6. icon="arrow-right"
  7. :rotate="open ? 90 : 0"
  8. :innerStyle="{ transition: 'transform 0.3s ease-in-out' }"
  9. @click="toggleOpen"
  10. />
  11. <CheckBox
  12. :key="item.value"
  13. :name="item.value"
  14. :text="item.text"
  15. :disabled="item.disable"
  16. />
  17. </FlexRow>
  18. <CollapseBox :open="open" :anim="false">
  19. <FlexCol :padding="[10,0,10,30]">
  20. <Loadmore
  21. v-if="loading || loadError"
  22. :status="loading ? 'loading' : 'error'"
  23. :errorText="loadError"
  24. @retry="loadChildren"
  25. />
  26. <CheckBoxTreeListItemWrapper
  27. v-for="child in item.children"
  28. :key="child.value"
  29. :item="child"
  30. />
  31. </FlexCol>
  32. </CollapseBox>
  33. </FlexCol>
  34. </template>
  35. <script setup lang="ts">
  36. import { inject, ref } from 'vue';
  37. import type { CheckBoxTreeListItem } from './CheckBoxTreeList.vue';
  38. import CollapseBox from '@/components/display/CollapseBox.vue';
  39. import CheckBox from '@/components/form/CheckBox.vue';
  40. import FlexCol from '@/components/layout/FlexCol.vue';
  41. import FlexRow from '@/components/layout/FlexRow.vue';
  42. import IconButton from '@/components/basic/IconButton.vue';
  43. import CheckBoxTreeListItemWrapper from './CheckBoxTreeListItemWrapper.vue';
  44. import Loadmore from '@/components/display/loading/Loadmore.vue';
  45. const props = defineProps<{
  46. item: CheckBoxTreeListItem,
  47. }>();
  48. const open = ref(false);
  49. const loading = ref(false);
  50. const loadError = ref('');
  51. const loadData = inject('loadData') as (pid?: number) => Promise<CheckBoxTreeListItem[]>;
  52. function toggleOpen() {
  53. open.value = !open.value;
  54. if (open.value && (!props.item.children || props.item.children.length === 0))
  55. loadChildren();
  56. }
  57. function loadChildren() {
  58. loading.value = true;
  59. loadData(props.item.value).then((children) => {
  60. props.item.children = children;
  61. loadError.value = '';
  62. }).catch((err) => {
  63. props.item.children = [];
  64. loadError.value = '' + err;
  65. }).finally(() => {
  66. loading.value = false;
  67. });
  68. }
  69. </script>
  70. <style lang="scss">
  71. .nana-collapse-item-icon {
  72. transition: transform 0.3s ease-in-out;
  73. &.open {
  74. transform: rotate(180deg);
  75. }
  76. }
  77. </style>