index.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <template>
  2. <div class="upload">
  3. <el-upload class="avatar-uploader"
  4. style="line-height: 0;display: inline-block"
  5. action="/api-web/uploadFile"
  6. :headers="headers"
  7. :show-file-list="false"
  8. v-loading="uploadImgLoading"
  9. :accept="accept"
  10. :on-success="handleImgSuccess"
  11. :on-error="handleUploadImgError"
  12. :before-upload="beforeImgUpload">
  13. <img v-if="imgUrl"
  14. :src="imgUrl"
  15. class="avatar" />
  16. <i v-else
  17. class="el-icon-plus avatar-uploader-icon"></i>
  18. </el-upload>
  19. </div>
  20. </template>
  21. <script>
  22. import load from "@/utils/loading";
  23. import { getToken } from "@/utils/auth";
  24. export default {
  25. data () {
  26. return {
  27. headers: {
  28. Authorization: getToken()
  29. },
  30. uploadImgLoading: false,
  31. imgUrl: null,
  32. };
  33. },
  34. props: {
  35. value: {
  36. // 组件状态
  37. type: String,
  38. },
  39. accept: {
  40. type: String,
  41. default () {
  42. return '.jpg, .jpeg, .png, .gif'
  43. }
  44. },
  45. imageSizeM: { // 默认2M
  46. type: Number,
  47. default () {
  48. return 2
  49. }
  50. },
  51. imageWidthM: { // 默认2M
  52. type: Number,
  53. default () {
  54. return null
  55. }
  56. },
  57. imageHeightM: { // 默认2M
  58. type: Number,
  59. default () {
  60. return null
  61. }
  62. },
  63. imageType: { // 检测类型
  64. type: Object,
  65. default () {
  66. return {
  67. "image/png": true,
  68. "image/jpeg": true,
  69. "image/jpg": true,
  70. "image/gif": true
  71. }
  72. }
  73. }
  74. },
  75. mounted () {
  76. this.imgUrl = this.value
  77. },
  78. methods: {
  79. beforeImgUpload (file) {
  80. const isImage = this.imageType[file.type];
  81. const isLt2M = file.size / 1024 / 1024 < this.imageSizeM;
  82. const imageWidth = this.imageWidthM
  83. const imageHeigh = this.imageHeightM
  84. const _URL = window.URL || window.webkitURL
  85. const isSize = new Promise((resolve, reject) => {
  86. const img = new Image()
  87. img.onload = function () {
  88. if (imageWidth && imageHeigh) {
  89. this.width === imageWidth && this.height === imageHeigh ? resolve() : reject(`请上传${imageWidth}x${imageHeigh}尺寸图片`)
  90. } else if (imageWidth && !imageHeigh) {
  91. this.width === imageWidth ? resolve() : reject(`请上传宽为${imageWidth}的图片`)
  92. } else if (!imageWidth && imageHeigh) {
  93. this.height === imageHeigh ? resolve() : reject(`请上传高为${imageHeigh}的图片`)
  94. }
  95. else {
  96. resolve()
  97. }
  98. }
  99. img.src = _URL.createObjectURL(file)
  100. }).then(
  101. () => {
  102. return file
  103. },
  104. (src) => {
  105. this.$message.error(src);
  106. this.uploadImgLoading = false
  107. return Promise.reject()
  108. }
  109. )
  110. if (!isImage) {
  111. this.$message.error("只能上传图片格式!");
  112. }
  113. if (!isLt2M) {
  114. this.$message.error(`上传图片大小不能超过 ${this.imageSizeM}MB!`);
  115. }
  116. if (isImage && isLt2M && isSize) {
  117. this.uploadImgLoading = true
  118. }
  119. return isImage && isLt2M && isSize;
  120. },
  121. handleUploadImgError (file) {
  122. this.uploadImgLoading = false
  123. this.$message.error('上传失败')
  124. },
  125. handleImgSuccess (res, file) {
  126. this.uploadImgLoading = false
  127. this.imgUrl = res.data.url
  128. this.$emit('input', res.data.url)
  129. },
  130. },
  131. watch: {
  132. value (newValue) {
  133. this.imgUrl = newValue
  134. },
  135. },
  136. beforeDestroy () {
  137. },
  138. };
  139. </script>
  140. <style lang="scss" scoped>
  141. /deep/.avatar-uploader .el-upload,
  142. /deep/.upload-demo .el-upload {
  143. border-radius: 6px;
  144. cursor: pointer;
  145. position: relative;
  146. overflow: hidden;
  147. }
  148. .avatar-uploader .el-upload:hover {
  149. border-color: #409eff;
  150. }
  151. .avatar-uploader-icon {
  152. border: 1px dashed #d9d9d9;
  153. font-size: 28px;
  154. color: #8c939d;
  155. width: 120px;
  156. height: 120px;
  157. line-height: 120px;
  158. text-align: center;
  159. }
  160. .avatar {
  161. width: 120px;
  162. height: 120px;
  163. display: block;
  164. }
  165. .ivu-upload {
  166. display: none;
  167. }
  168. </style>