upload.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <script>
  2. import ajax from './ajax';
  3. import UploadDragger from './upload-dragger.vue';
  4. export default {
  5. inject: ['uploader'],
  6. components: {
  7. UploadDragger
  8. },
  9. props: {
  10. type: String,
  11. action: {
  12. type: String,
  13. required: true
  14. },
  15. name: {
  16. type: String,
  17. default: 'file'
  18. },
  19. data: Object,
  20. headers: Object,
  21. withCredentials: Boolean,
  22. multiple: Boolean,
  23. accept: String,
  24. onStart: Function,
  25. onProgress: Function,
  26. onSuccess: Function,
  27. onError: Function,
  28. beforeUpload: Function,
  29. drag: Boolean,
  30. onPreview: {
  31. type: Function,
  32. default: function() {}
  33. },
  34. onRemove: {
  35. type: Function,
  36. default: function() {}
  37. },
  38. fileList: Array,
  39. autoUpload: Boolean,
  40. listType: String,
  41. httpRequest: {
  42. type: Function,
  43. default: ajax
  44. },
  45. disabled: Boolean,
  46. limit: Number,
  47. onExceed: Function
  48. },
  49. data() {
  50. return {
  51. mouseover: false,
  52. reqs: {}
  53. };
  54. },
  55. methods: {
  56. isImage(str) {
  57. return str.indexOf('image') !== -1;
  58. },
  59. handleChange(ev) {
  60. const files = ev.target.files;
  61. if (!files) return;
  62. this.uploadFiles(files);
  63. },
  64. uploadFiles(files) {
  65. if (this.limit && this.fileList.length + files.length > this.limit) {
  66. this.onExceed && this.onExceed(files, this.fileList);
  67. return;
  68. }
  69. let postFiles = Array.prototype.slice.call(files);
  70. if (!this.multiple) { postFiles = postFiles.slice(0, 1); }
  71. if (postFiles.length === 0) { return; }
  72. postFiles.forEach(rawFile => {
  73. this.onStart(rawFile);
  74. if (this.autoUpload) this.upload(rawFile);
  75. });
  76. },
  77. upload(rawFile, file) {
  78. this.$refs.input.value = null;
  79. if (!this.beforeUpload) {
  80. return this.post(rawFile);
  81. }
  82. const before = this.beforeUpload(rawFile);
  83. if (before && before.then) {
  84. before.then(processedFile => {
  85. if (Object.prototype.toString.call(processedFile) === '[object File]') {
  86. this.post(processedFile);
  87. } else {
  88. this.post(rawFile);
  89. }
  90. }, () => {
  91. this.onRemove(null, rawFile);
  92. });
  93. } else if (before !== false) {
  94. this.post(rawFile);
  95. } else {
  96. this.onRemove(null, rawFile);
  97. }
  98. },
  99. abort(file) {
  100. const { reqs } = this;
  101. if (file) {
  102. let uid = file;
  103. if (file.uid) uid = file.uid;
  104. if (reqs[uid]) {
  105. reqs[uid].abort();
  106. }
  107. } else {
  108. Object.keys(reqs).forEach((uid) => {
  109. if (reqs[uid]) reqs[uid].abort();
  110. delete reqs[uid];
  111. });
  112. }
  113. },
  114. post(rawFile) {
  115. const { uid } = rawFile;
  116. const options = {
  117. headers: this.headers,
  118. withCredentials: this.withCredentials,
  119. file: rawFile,
  120. data: this.data,
  121. filename: this.name,
  122. action: this.action,
  123. onProgress: e => {
  124. this.onProgress(e, rawFile);
  125. },
  126. onSuccess: res => {
  127. this.onSuccess(res, rawFile);
  128. delete this.reqs[uid];
  129. },
  130. onError: err => {
  131. this.onError(err, rawFile);
  132. delete this.reqs[uid];
  133. }
  134. };
  135. const req = this.httpRequest(options);
  136. this.reqs[uid] = req;
  137. if (req && req.then) {
  138. req.then(options.onSuccess, options.onError);
  139. }
  140. },
  141. handleClick() {
  142. if (!this.disabled) {
  143. this.$refs.input.value = null;
  144. this.$refs.input.click();
  145. }
  146. },
  147. handleKeydown(e) {
  148. if (e.keyCode === 13 || e.keyCode === 32) {
  149. this.handleClick();
  150. }
  151. }
  152. },
  153. render(h) {
  154. let {
  155. handleClick,
  156. drag,
  157. name,
  158. handleChange,
  159. multiple,
  160. accept,
  161. listType,
  162. uploadFiles,
  163. disabled,
  164. handleKeydown
  165. } = this;
  166. const data = {
  167. class: {
  168. 'el-upload': true
  169. },
  170. on: {
  171. click: handleClick,
  172. keydown: handleKeydown
  173. }
  174. };
  175. data.class[`el-upload--${listType}`] = true;
  176. return (
  177. <div {...data} tabindex="0" >
  178. {
  179. drag
  180. ? <upload-dragger disabled={disabled} on-file={uploadFiles}>{this.$slots.default}</upload-dragger>
  181. : this.$slots.default
  182. }
  183. <input class="el-upload__input" type="file" ref="input" name={name} on-change={handleChange} multiple={multiple} accept={accept}></input>
  184. </div>
  185. );
  186. }
  187. };
  188. </script>