index.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <template>
  2. <div class="upload">
  3. <el-upload v-model:file-list="fileList" :class="{ hide: fileList.length >= limit }" :accept="accept" list-type="picture-card" :limit="limit" :multiple="multiple" :headers="headers" :before-upload="beforeAvatarUpload" :action="uploadUrl"
  4. :on-success="updateImg" :on-preview="handlePictureCardPreview" :on-remove="updateImg">
  5. <el-icon>
  6. <ele-Plus />
  7. </el-icon>
  8. </el-upload>
  9. <el-dialog v-model="dialogVisible">
  10. <img class="preview" :src="dialogImageUrl" alt="Preview Image" />
  11. </el-dialog>
  12. <!-- 上传单张图片 -->
  13. <!-- <uploadVue @set-img="youImg=$event" ></uploadVue> -->
  14. <!-- 上传多长图片 需增加limit属性,设定图片最多张数 -->
  15. <!-- <uploadVue @set-imgs="youImgs=$event" :limit="2"></uploadVue> -->
  16. <!-- 上传单张图片,img属性可以恢复表单图片显示 -->
  17. <!-- <uploadVue img="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" @set-img="youImg=$event"></uploadVue> -->
  18. <!-- 上传多张图片,imgs属性可以恢复表单图片多图显示 需增加limit属性,设定图片最多张数 -->
  19. <!-- <uploadVue :imgs="['https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png']" @set-imgs="youImgs=$event" :limit="2"></uploadVue> -->
  20. </div>
  21. </template>
  22. <script lang="ts" setup>
  23. import { ref, PropType, watch } from 'vue';
  24. import { ElMessage } from 'element-plus';
  25. import type { UploadProps } from 'element-plus';
  26. import getOrigin from '/@/utils/origin'
  27. const uploadUrl: string = getOrigin(import.meta.env.VITE_API_URL + '/common/singleImg');
  28. const headers = {
  29. Authorization: 'Bearer ' + JSON.parse(sessionStorage.token),
  30. };
  31. const emit = defineEmits(['setImg', 'setImgs']);
  32. const props = defineProps({
  33. multiple: {
  34. type: Boolean,
  35. default: false,
  36. },
  37. accept: {
  38. type: String,
  39. default: '.jpg,.png,.jpeg,.gif',
  40. },
  41. limit: {
  42. type: Number,
  43. default: 1,
  44. },
  45. imgs: {
  46. type: Array as PropType<string[]>,
  47. default: () => [],
  48. },
  49. img: {
  50. type: String,
  51. default: '',
  52. },
  53. });
  54. const fileList = ref<any[]>([
  55. // {
  56. // name: '',
  57. // url: '',
  58. // },
  59. ]);
  60. const updateImg = () => {
  61. const list = fileList.value.map((item) => {
  62. if (item.response) {
  63. return getOrigin(import.meta.env.VITE_SERVER_URL + '/' + item.response?.data?.path);
  64. // return item.response?.data?.path;
  65. } else {
  66. return item.url;
  67. }
  68. });
  69. if (props.limit === 1) {
  70. emit('setImg', list[0]);
  71. } else {
  72. emit('setImgs', list);
  73. }
  74. };
  75. // 如果传入图片输入,设置图片显示
  76. watch(
  77. () => props.imgs,
  78. (imgs) => {
  79. if (imgs.length) {
  80. fileList.value = imgs.map((url) => ({ name: url, url }));
  81. updateImg();
  82. }
  83. },
  84. { immediate: true }
  85. );
  86. // 传入单独图片,设置图片显示
  87. watch(
  88. () => props.img,
  89. (img) => {
  90. if (img) {
  91. fileList.value = [{ name: img, url: img }];
  92. updateImg();
  93. }
  94. },
  95. { immediate: true }
  96. );
  97. const dialogImageUrl = ref('');
  98. const dialogVisible = ref(false);
  99. const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  100. dialogImageUrl.value = uploadFile.url!;
  101. dialogVisible.value = true;
  102. };
  103. const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  104. if (rawFile.size / 1024 / 1024 > 2) {
  105. ElMessage.error('图片不能超过2MB!');
  106. return false;
  107. }
  108. return true;
  109. };
  110. </script>
  111. <style scoped>
  112. .hide ::v-deep(.el-upload--picture-card) {
  113. display: none;
  114. }
  115. .preview {
  116. max-width: 100%;
  117. max-height: 60vh;
  118. display: block;
  119. margin: 0 auto;
  120. }
  121. </style>