ImageLine.vue 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <template>
  2. <div class="w-100 d-flex flex-row align-stretch" :style="{ gap: gap }">
  3. <slot
  4. name="item"
  5. v-for="(v, k) in showData"
  6. :key="k"
  7. :item="v"
  8. :index="k"
  9. :width="`calc(${100 / visibleCount}% - ${gap})`"
  10. :height="imageHeight"
  11. :url="imagekey ? v[imagekey] : v"
  12. >
  13. <img
  14. :src="imagekey ? v[imagekey] : v"
  15. :style="{
  16. width: `calc(${100 / visibleCount}% - ${gap})`,
  17. height: imageHeight,
  18. borderRadius: '5px',
  19. objectFit: 'cover',
  20. }"
  21. tabindex="0"
  22. @click="()=>emit('itemClick', v)"
  23. />
  24. </slot>
  25. <div
  26. v-if="visibleCount > maxCount"
  27. class="d-flex flex-column align-center justify-center bg-light cursor-pointer radius-base"
  28. :style="{
  29. width: `calc(${100 / visibleCount}% - ${gap})`,
  30. height: imageHeight,
  31. borderRadius: '5px',
  32. objectFit: 'cover',
  33. }"
  34. tabindex="0"
  35. @click="()=>emit('moreClick')"
  36. >
  37. <div class="w-100 h-100 bg-light d-flex flex-column align-center justify-center">
  38. <div class="size-s">+{{ data.length - maxCount }}</div>
  39. </div>
  40. </div>
  41. </div>
  42. </template>
  43. <script setup lang="ts">
  44. import { computed, type PropType } from 'vue';
  45. const props = defineProps({
  46. maxCount : {
  47. type: Number,
  48. default: 3,
  49. },
  50. imagekey : {
  51. type: String,
  52. default: undefined,
  53. },
  54. imageHeight : {
  55. type: String,
  56. default: undefined,
  57. },
  58. gap: {
  59. type: String,
  60. default: '10px',
  61. },
  62. data: {
  63. type: Object as PropType<any[]>,
  64. default: null,
  65. },
  66. scroll: {
  67. type: Boolean,
  68. default: true,
  69. }
  70. })
  71. const showData = computed(() => {
  72. if (!props.data)
  73. return []
  74. return props.data.slice(0, props.maxCount)
  75. });
  76. const visibleCount = computed(() => {
  77. if (!props.data)
  78. return 0
  79. return props.data.length > props.maxCount ? (props.maxCount + 1) : props.maxCount
  80. });
  81. const emit = defineEmits([
  82. "itemClick" ,
  83. 'moreClick'
  84. ])
  85. </script>