uploads.vue 4.7 KB

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