AlbumDeletable.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <template>
  2. <view class="album-deletable">
  3. <view
  4. class="album-item"
  5. v-for="(item, index) in urls"
  6. :key="index"
  7. :style="itemStyle"
  8. >
  9. <image
  10. class="album-image"
  11. :src="getSrc(item)"
  12. mode="aspectFill"
  13. @tap="previewFullImage ? onPreviewTap(index) : ''"
  14. />
  15. <view
  16. v-if="deletable"
  17. class="delete-btn"
  18. @tap.stop="handleDelete(index, item)"
  19. >
  20. <u-icon name="close-circle-fill" color="#ff4d4f" size="22"></u-icon>
  21. </view>
  22. </view>
  23. </view>
  24. </template>
  25. <script>
  26. export default {
  27. name: 'AlbumDeletable',
  28. props: {
  29. urls: {
  30. type: Array,
  31. default: () => [],
  32. },
  33. keyName: {
  34. type: String,
  35. default: '',
  36. },
  37. singleSize: {
  38. type: [String, Number],
  39. default: 180,
  40. },
  41. multipleSize: {
  42. type: [String, Number],
  43. default: 170,
  44. },
  45. space: {
  46. type: [String, Number],
  47. default: 12,
  48. },
  49. rowCount: {
  50. type: [String, Number],
  51. default: 3,
  52. },
  53. deletable: {
  54. type: Boolean,
  55. default: true,
  56. },
  57. previewFullImage: {
  58. type: Boolean,
  59. default: true,
  60. },
  61. },
  62. computed: {
  63. itemStyle() {
  64. const size =
  65. this.urls.length === 1
  66. ? uni.$u.addUnit(this.singleSize)
  67. : uni.$u.addUnit(this.multipleSize);
  68. return {
  69. width: size,
  70. height: size,
  71. marginRight: uni.$u.addUnit(this.space),
  72. marginBottom: uni.$u.addUnit(this.space),
  73. };
  74. },
  75. },
  76. methods: {
  77. getSrc(item) {
  78. return uni.$u.test.object(item)
  79. ? (this.keyName && item[this.keyName]) || item.src
  80. : item;
  81. },
  82. onPreviewTap(index) {
  83. const urls = this.urls.map((item) => this.getSrc(item));
  84. uni.previewImage({
  85. current: urls[index],
  86. urls,
  87. });
  88. },
  89. handleDelete(index, item) {
  90. this.$emit('delete', index, item);
  91. },
  92. },
  93. };
  94. </script>
  95. <style scoped lang="scss">
  96. .album-deletable {
  97. display: flex;
  98. flex-wrap: wrap;
  99. }
  100. .album-item {
  101. position: relative;
  102. flex-shrink: 0;
  103. }
  104. .album-image {
  105. width: 100%;
  106. height: 100%;
  107. border-radius: 12rpx;
  108. }
  109. .delete-btn {
  110. position: absolute;
  111. top: -10rpx;
  112. right: -10rpx;
  113. width: 44rpx;
  114. height: 44rpx;
  115. display: flex;
  116. align-items: center;
  117. justify-content: center;
  118. background: #fff;
  119. border-radius: 50%;
  120. z-index: 2;
  121. }
  122. </style>