image.vue 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <template>
  2. <div>
  3. <el-upload
  4. :action="`${path}/fileUploadAndDownload/upload`"
  5. :before-upload="beforeImageUpload"
  6. :multiple="false"
  7. :on-success="handleImageSuccess"
  8. :show-file-list="false"
  9. >
  10. <el-button v-preReClick type="primary">压缩上传</el-button>
  11. </el-upload>
  12. </div>
  13. </template>
  14. <script setup>
  15. import ImageCompress from '@/utils/image'
  16. import { ref, defineProps, defineEmits } from 'vue'
  17. import { ElMessage } from 'element-plus'
  18. import { useUserStore } from '@/pinia/modules/user'
  19. defineOptions({
  20. name: 'UploadImage'
  21. })
  22. const emit = defineEmits(['on-success'])
  23. const props = defineProps({
  24. imageUrl: {
  25. type: String,
  26. default: ''
  27. },
  28. fileSize: {
  29. type: Number,
  30. default: 2048 // 2M 超出后执行压缩
  31. },
  32. maxWH: {
  33. type: Number,
  34. default: 1920 // 图片长宽上限
  35. }
  36. })
  37. const path = ref(import.meta.env.VITE_BASE_API)
  38. const userStore = useUserStore()
  39. const beforeImageUpload = file => {
  40. const isJPG = file.type === 'image/jpeg'
  41. const isPng = file.type === 'image/png'
  42. if (!isJPG && !isPng) {
  43. ElMessage.error('上传头像图片只能是 jpg或png 格式!')
  44. return false
  45. }
  46. const isRightSize = file.size / 1024 < props.fileSize
  47. if (!isRightSize) {
  48. // 压缩
  49. const compress = new ImageCompress(file, props.fileSize, props.maxWH)
  50. return compress.compress()
  51. }
  52. return isRightSize
  53. }
  54. const handleImageSuccess = res => {
  55. const { data } = res
  56. if (data.file) {
  57. emit('on-success', data.file.url)
  58. }
  59. }
  60. </script>
  61. <style lang="scss" scoped>
  62. .image-uploader {
  63. border: 1px dashed #d9d9d9;
  64. width: 180px;
  65. border-radius: 6px;
  66. cursor: pointer;
  67. position: relative;
  68. overflow: hidden;
  69. }
  70. .image-uploader {
  71. border-color: #409eff;
  72. }
  73. .image-uploader-icon {
  74. font-size: 28px;
  75. color: #8c939d;
  76. width: 178px;
  77. height: 178px;
  78. line-height: 178px;
  79. text-align: center;
  80. }
  81. .image {
  82. width: 178px;
  83. height: 178px;
  84. display: block;
  85. }
  86. </style>