imgUp.vue 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <template>
  2. <view class="my-image-uploader" :class="{ disabled: props.disabled }">
  3. <view class="img-list">
  4. <image v-for="(item, index) in fileList" :key="index" :src="item" class="img" mode="aspectFill"
  5. @click="chooseImage" />
  6. </view>
  7. <view class="upload-btn" v-if="fileList.length < maxCount" @click="chooseImage">
  8. <u-icon name="plus" size="40" color="#c0c4cc"></u-icon>
  9. </view>
  10. <CameraUpload ref="cameraUploadRef" @confirm="onCameraConfirm" />
  11. </view>
  12. </template>
  13. <script setup>
  14. import { ref } from 'vue'
  15. import { $upload, Toast } from '@/utils'
  16. import { t } from "@/locale"
  17. import CameraUpload from "./CameraUpload.vue";
  18. const props = defineProps({
  19. modelValue: { type: Array, default: () => [] },
  20. maxCount: { type: Number, default: 1 },
  21. disabled: {
  22. type: Boolean,
  23. default: false
  24. },
  25. })
  26. const emit = defineEmits(['update:modelValue', 'success', 'delete', 'error'])
  27. const fileList = ref([...props.modelValue])
  28. const cameraUploadRef = ref(null)
  29. const chooseImage = () => {
  30. if (props.disabled) return;
  31. cameraUploadRef.value && cameraUploadRef.value.open()
  32. }
  33. const onCameraConfirm = async (url) => {
  34. try {
  35. fileList.value = [];
  36. fileList.value.push(url)
  37. emit('update:modelValue', fileList.value)
  38. emit('success', url)
  39. } catch (error) {
  40. Toast.error(t('上传失败'))
  41. emit('error', error)
  42. }
  43. }
  44. </script>
  45. <style lang="less" scoped>
  46. .my-image-uploader {
  47. display: flex;
  48. flex-wrap: wrap;
  49. &.disabled {
  50. opacity: 0.5;
  51. pointer-events: none;
  52. }
  53. .img-list {
  54. display: flex;
  55. flex-wrap: wrap;
  56. gap: 20rpx;
  57. .img {
  58. width: 150rpx;
  59. height: 150rpx;
  60. border-radius: 8rpx;
  61. background: #f5f7fa;
  62. }
  63. }
  64. .upload-btn {
  65. width: 150rpx;
  66. height: 150rpx;
  67. border: 1px dashed #c0c4cc;
  68. border-radius: 8rpx;
  69. display: flex;
  70. align-items: center;
  71. justify-content: center;
  72. background: #f5f7fa;
  73. }
  74. }
  75. </style>