uploads.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <template>
  2. <div>
  3. <el-upload
  4. ref="upload"
  5. :accept="accept"
  6. :action="action"
  7. :data="data"
  8. :auto-upload="auto"
  9. :drag="drag"
  10. :file-list="tmpFileList"
  11. :headers="headers"
  12. :limit="max"
  13. :list-type="listType"
  14. :multiple="max > 1"
  15. :on-change="handleChange"
  16. :on-exceed="maxChange"
  17. :on-progress="progress"
  18. :on-remove="remove"
  19. :on-error="onError"
  20. :on-success="success"
  21. :show-file-list="showList"
  22. style="width: 100%"
  23. >
  24. <div v-if="drag">
  25. <i class="el-icon-upload"></i>
  26. <div class="el-upload__text">
  27. 将文件/图片拖到此处,或<em>点击上传</em>
  28. </div>
  29. </div>
  30. <div v-else class="flex flex-justify-start">
  31. <el-button
  32. v-if="showBtn"
  33. :loading="loading"
  34. icon="el-icon-upload"
  35. plain
  36. size="mini"
  37. type="primary"
  38. >{{ btn }}
  39. </el-button>
  40. </div>
  41. <slot></slot>
  42. </el-upload>
  43. </div>
  44. </template>
  45. <script>
  46. import { Base64 } from 'js-base64'
  47. import { getToken } from '../utils/auth.js'
  48. import website from '@/config/website'
  49. import api from '@/api'
  50. export default {
  51. name: 'uploadFile', // 文件上传
  52. props: {
  53. showBtn: {
  54. type: Boolean,
  55. default: true
  56. },
  57. drag: {
  58. type: Boolean,
  59. default: false
  60. },
  61. showList: {
  62. type: Boolean,
  63. default: false
  64. },
  65. data: Object,
  66. auto: {
  67. type: Boolean,
  68. default: false
  69. },
  70. accept: {
  71. type: String,
  72. default: ''
  73. },
  74. max: {
  75. type: Number,
  76. default: 1
  77. },
  78. listType: {
  79. type: String,
  80. default: 'text'
  81. },
  82. btnText: {
  83. type: String,
  84. default: '点击上传'
  85. },
  86. action: {
  87. type: String,
  88. default: api.uploadPath
  89. },
  90. files: {
  91. type: Array,
  92. default() {
  93. return null
  94. }
  95. }
  96. },
  97. watch: {
  98. btnText: {
  99. handler(val) {
  100. this.btn = val
  101. },
  102. immediate: true
  103. }
  104. },
  105. data() {
  106. return {
  107. loading: false,
  108. btn: '点击上传',
  109. tmpFileList: [],
  110. fileList: [],
  111. headers: {
  112. Authorization: `Basic ${Base64.encode(
  113. `${website.clientId}:${website.clientSecret}`
  114. )}`,
  115. 'Blade-Auth': 'bearer ' + getToken()
  116. }
  117. }
  118. },
  119. mounted() {
  120. this.setFiles(this.files, 'originalFileName')
  121. },
  122. methods: {
  123. setFiles(fileList, name) {
  124. // 文件回填 (参数:文件列表,文件名的字段name)
  125. if (!fileList || fileList.length === 0) return
  126. const files = []
  127. fileList.forEach((item, index) => {
  128. files.push({
  129. name: item[name] || '文件' + index + 1,
  130. response: {
  131. code: 200,
  132. success: true,
  133. data: [item]
  134. },
  135. status: 'success'
  136. })
  137. })
  138. this.fileList = files
  139. },
  140. progress(event, file, fileList) {
  141. if (file.status === 'ready') {
  142. this.loading = true
  143. this.btn = '正在上传'
  144. } else if (file.status === 'success') {
  145. this.loading = false
  146. this.btn = '点击上传'
  147. }
  148. this.$emit('progress')
  149. },
  150. handleChange(file, fileList) {
  151. this.tmpFileList = fileList
  152. this.$emit('before', this.tmpFileList)
  153. },
  154. maxChange() {
  155. if (this.max === 1) {
  156. // 只有一张图的时候超出进行覆盖
  157. this.fileList = []
  158. } else {
  159. this.$message.warning(`最多只能上传${this.max}个文件`)
  160. }
  161. },
  162. beforeUpload(file) {
  163. this.loading = true
  164. console.log(file)
  165. this.$emit('before', file)
  166. },
  167. success() {
  168. this.loading = false
  169. this.btn = '点击上传'
  170. const finishList = this.tmpFileList.filter(
  171. sub => sub.status === 'success'
  172. )
  173. if (finishList.length === this.tmpFileList.length) {
  174. this.$emit('success', {
  175. fileList: this.tmpFileList
  176. })
  177. setTimeout(() => {
  178. this.$refs.upload.clearFiles()
  179. this.tmpFileList = []
  180. this.speed = ''
  181. }, 2000)
  182. }
  183. },
  184. remove(file, fileList) {
  185. const ids = fileList.map(e => e.response.data[0].id)
  186. this.$emit('remove', {
  187. file,
  188. fileList,
  189. ids
  190. })
  191. },
  192. submit() {
  193. this.$refs.upload.submit()
  194. },
  195. onError(res, file, fileList) {
  196. const error = JSON.parse(res.message)
  197. this.$confirm(error.msg, {
  198. confirmButtonText: '确定',
  199. type: 'warning'
  200. }).then(() => {
  201. this.$emit('error')
  202. })
  203. }
  204. }
  205. }
  206. </script>
  207. <style lang="scss" scoped>
  208. .custom-upload {
  209. :deep(.el-upload-list__item-name) {
  210. white-space: pre-wrap;
  211. width: 100%;
  212. }
  213. }
  214. </style>