upload.vue 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <script setup lang="tsx">
  2. import { ref } from "vue";
  3. import ReCropper from "@/components/ReCropper";
  4. import { formatBytes } from "@pureadmin/utils";
  5. const props = defineProps({
  6. imgSrc: String
  7. });
  8. const emit = defineEmits(["cropper"]);
  9. const infos = ref();
  10. const popoverRef = ref();
  11. const refCropper = ref();
  12. const showPopover = ref(false);
  13. const cropperImg = ref<string>("");
  14. function onCropper({ base64, blob, info }) {
  15. infos.value = info;
  16. cropperImg.value = base64;
  17. emit("cropper", { base64, blob, info });
  18. }
  19. function hidePopover() {
  20. popoverRef.value.hide();
  21. }
  22. defineExpose({ hidePopover });
  23. </script>
  24. <template>
  25. <div v-loading="!showPopover" element-loading-background="transparent">
  26. <el-popover
  27. ref="popoverRef"
  28. :visible="showPopover"
  29. placement="right"
  30. width="18vw"
  31. >
  32. <template #reference>
  33. <div class="w-[18vw]">
  34. <ReCropper
  35. ref="refCropper"
  36. :src="props.imgSrc"
  37. circled
  38. @cropper="onCropper"
  39. @readied="showPopover = true"
  40. />
  41. <p v-show="showPopover" class="mt-1 text-center">
  42. 温馨提示:右键上方裁剪区可开启功能菜单
  43. </p>
  44. </div>
  45. </template>
  46. <div class="flex flex-wrap justify-center items-center text-center">
  47. <el-image
  48. v-if="cropperImg"
  49. :src="cropperImg"
  50. :preview-src-list="Array.of(cropperImg)"
  51. fit="cover"
  52. />
  53. <div v-if="infos" class="mt-1">
  54. <p>
  55. 图像大小:{{ parseInt(infos.width) }} ×
  56. {{ parseInt(infos.height) }}像素
  57. </p>
  58. <p>
  59. 文件大小:{{ formatBytes(infos.size) }}({{ infos.size }} 字节)
  60. </p>
  61. </div>
  62. </div>
  63. </el-popover>
  64. </div>
  65. </template>