CollapseItem.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <template>
  2. <FlexView direction="column" :data-position="position">
  3. <slot
  4. name="cell"
  5. :state="state"
  6. :title="title"
  7. :value="value"
  8. :label="label"
  9. :size="size"
  10. :icon="icon"
  11. >
  12. <Cell
  13. :title="title"
  14. :value="value"
  15. :label="label"
  16. :size="size"
  17. :icon="icon"
  18. :touchable="!props.disabled"
  19. :innerStyle="{
  20. opacity: props.disabled ? 0.7 : 1,
  21. }"
  22. :topBorder="props.border"
  23. @click="context.itemClick(id)"
  24. >
  25. <!-- TODO: Fix -->
  26. <!-- #ifndef MP -->
  27. <template v-if="$slots.icon" #leftIcon>
  28. <slot name="icon" />
  29. </template>
  30. <template v-if="$slots.label" #label>
  31. <slot name="label" />
  32. </template>
  33. <template v-if="$slots.value" #value>
  34. <slot name="value" />
  35. </template>
  36. <template v-if="$slots.title" #title>
  37. <slot name="title" />
  38. </template>
  39. <!-- #endif -->
  40. <template #rightIcon>
  41. <Icon
  42. icon="arrow-down"
  43. :rotate="state ? 180 : 0"
  44. :innerStyle="{ transition: 'transform 0.3s ease-in-out' }"
  45. />
  46. </template>
  47. </Cell>
  48. </slot>
  49. <CollapseBox :open="state" :anim-duration="context.animDuration.value" :name="'' + (name || position)">
  50. <slot />
  51. </CollapseBox>
  52. </FlexView>
  53. </template>
  54. <script setup lang="ts">
  55. import { computed, inject } from 'vue';
  56. import FlexView from '../layout/FlexView.vue';
  57. import type { CollapseContext } from './Collapse.vue';
  58. import Cell from '../basic/Cell.vue';
  59. import CollapseBox from './CollapseBox.vue';
  60. import Icon from '../basic/Icon.vue';
  61. import { useChildLinkChild } from '../composeabe/ChildItem';
  62. export interface CollapseProps {
  63. /**
  64. * 当前面板的唯一标识符,默认为索引值
  65. */
  66. name?: number | string;
  67. /**
  68. * 标题栏左侧图标名称或图片链接,等同于 Icon 组件的 icon 属性
  69. */
  70. icon?: string;
  71. /**
  72. * 标题栏大小,可选值为 large
  73. * @default 'medium'
  74. */
  75. size?: 'medium' | 'large';
  76. /**
  77. * 标题栏左侧内容
  78. */
  79. title?: string;
  80. /**
  81. * 标题栏右侧内容
  82. */
  83. value?: string;
  84. /**
  85. * 标题栏描述信息
  86. */
  87. label?: string;
  88. /**
  89. * 是否显示内边框
  90. */
  91. border?: boolean;
  92. /**
  93. * 是否禁用面板
  94. */
  95. disabled?: boolean;
  96. }
  97. const emit = defineEmits([ 'update:modelValue' ]);
  98. const props = defineProps<CollapseProps>();
  99. const context = inject<CollapseContext>('CollapseContext')!;
  100. const id = computed(() => props.name || position.value);
  101. const state = computed(() => context.activeName.value.includes(id.value));
  102. const { position } = useChildLinkChild(() => ({ index: context.getPosition(props.name) }));
  103. </script>