UploadButton.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <div :class="prefixCls">
  3. <Upload
  4. :action="uploadUrl"
  5. :headers="headers"
  6. :max-size="maxSize"
  7. :format="format"
  8. :accept="accept"
  9. :data="uploadDataDict"
  10. :before-upload="handleBeforeUpload"
  11. :on-format-error="handleFormatError"
  12. :on-exceeded-size="handleExceededSize"
  13. :on-error="handleError"
  14. :on-success="handleSuccess"
  15. :on-remove="handleRemove"
  16. :show-upload-list="false"
  17. ref="UploadComp"
  18. >
  19. <Button
  20. shape="circle"
  21. :type="btnType"
  22. :icon="btnIcon"
  23. :loading="loading"
  24. >{{ btnContent }}</Button
  25. >
  26. </Upload>
  27. <slot name="extra"></slot>
  28. <p
  29. :class="[
  30. {
  31. 'cc-tips-success': res.success,
  32. 'cc-tips-error': !res.success
  33. }
  34. ]"
  35. v-if="res.msg && !res.success"
  36. >
  37. {{ res.msg }}
  38. </p>
  39. </div>
  40. </template>
  41. <script>
  42. import { fileMD5 } from "../plugins/md5";
  43. const prefixCls = "cc-upload-button";
  44. export default {
  45. name: "upload-button",
  46. props: {
  47. btnIcon: {
  48. type: String
  49. },
  50. btnType: {
  51. type: String,
  52. default: "default"
  53. },
  54. btnContent: {
  55. type: String,
  56. default: "上传文件"
  57. },
  58. format: {
  59. type: Array,
  60. default() {
  61. return ["jpg", "png"];
  62. }
  63. },
  64. uploadUrl: {
  65. type: String,
  66. required: true
  67. },
  68. uploadData: {
  69. type: Object,
  70. default() {
  71. return {};
  72. }
  73. },
  74. maxSize: {
  75. type: Number,
  76. default: 10 * 1024
  77. },
  78. addFilenameParam: {
  79. type: String,
  80. default: "fileName"
  81. },
  82. autoUpload: {
  83. type: Boolean,
  84. default: true
  85. }
  86. },
  87. data() {
  88. return {
  89. prefixCls,
  90. modalIsShow: false,
  91. loading: false,
  92. headers: { md5: "" },
  93. uploadDataDict: {},
  94. file: null,
  95. res: {
  96. success: true,
  97. msg: ""
  98. }
  99. };
  100. },
  101. computed: {
  102. accept() {
  103. return this.format.map(el => `.${el}`).join();
  104. }
  105. },
  106. methods: {
  107. visibleChange(visible) {
  108. if (!visible) {
  109. this.res = {
  110. success: true,
  111. msg: ""
  112. };
  113. this.$refs.UploadComp.clearFiles();
  114. }
  115. },
  116. startUpload() {
  117. if (this.file) {
  118. this.loading = true;
  119. this.$refs.UploadComp.post(this.file);
  120. }
  121. },
  122. async handleBeforeUpload(file) {
  123. const md5 = await fileMD5(file);
  124. this.headers.md5 = md5;
  125. this.uploadDataDict = { ...this.uploadData, md5 };
  126. if (this.addFilenameParam)
  127. this.uploadDataDict[this.addFilenameParam] = file.name;
  128. this.res = {
  129. success: true,
  130. msg: ""
  131. };
  132. this.$emit("file-change", file);
  133. if (!this.autoUpload) {
  134. this.file = file;
  135. return Promise.reject();
  136. }
  137. this.loading = true;
  138. this.$refs.UploadComp.clearFiles();
  139. },
  140. handleError(error, response) {
  141. this.loading = false;
  142. this.res = {
  143. success: false,
  144. msg: response.message
  145. };
  146. },
  147. handleSuccess(response) {
  148. this.loading = false;
  149. this.res = {
  150. success: true,
  151. msg: "上传成功!"
  152. };
  153. this.$emit("upload-success", response);
  154. },
  155. handleFormatError() {
  156. this.res = {
  157. success: false,
  158. msg: "只支持文件格式为" + this.format.join("/")
  159. };
  160. this.loading = false;
  161. },
  162. handleExceededSize() {
  163. this.res = {
  164. success: false,
  165. msg: "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M"
  166. };
  167. this.loading = false;
  168. },
  169. handleRemove() {
  170. this.resData = "";
  171. },
  172. cancel() {
  173. this.modalIsShow = false;
  174. },
  175. open() {
  176. this.modalIsShow = true;
  177. }
  178. }
  179. };
  180. </script>