FileUpload.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <template>
  2. <div>
  3. <el-upload
  4. :action="action"
  5. :file-list="fileList"
  6. list-type="picture-card"
  7. :limit="limit"
  8. :accept="accept"
  9. :class="hideUpload || uploading ? 'hideUpload' : ''"
  10. :on-error="handleError"
  11. :before-upload="beforeUpload"
  12. :on-success="handleImageSuccess"
  13. multiple
  14. >
  15. <i slot="default" class="el-icon-plus"></i>
  16. <div slot="file" slot-scope="{ file }">
  17. <div>
  18. <img
  19. class="el-upload-list__item-thumbnail"
  20. :src="isPDF(file.url) ? pdf : file.url"
  21. alt="" />
  22. <span
  23. v-if="file.status === 'success'"
  24. class="el-upload-list__item-actions"
  25. >
  26. <span
  27. v-if="preview"
  28. class="el-upload-list__item-preview"
  29. @click="handlePreview(file)"
  30. >
  31. <i class="el-icon-zoom-in"></i>
  32. </span>
  33. <span
  34. v-if="download"
  35. class="el-upload-list__item-delete"
  36. @click="handleDownload(file)"
  37. >
  38. <i class="el-icon-download"></i>
  39. </span>
  40. <span
  41. v-if="deleted"
  42. class="el-upload-list__item-delete"
  43. @click="handleRemove(file)"
  44. >
  45. <i class="el-icon-delete"></i>
  46. </span>
  47. </span>
  48. <span
  49. v-else
  50. :class="[
  51. uploading ? 'uploading' : '',
  52. 'el-upload-list__item-actions',
  53. ]"
  54. >
  55. <i class="el-icon-loading" /><i style="font-size: 14px">上传中</i>
  56. </span>
  57. <!--<div style="word-break: break-all;
  58.  text-overflow: ellipsis;
  59.  display: -webkit-box;
  60.  -webkit-box-orient: vertical;
  61.  -webkit-line-clamp: 2;
  62.  overflow: hidden;">{{ file.name+'.'+file.ext }}</div>-->
  63. </div>
  64. </div>
  65. </el-upload>
  66. <el-dialog :visible.sync="previewVisible">
  67. <img width="100%" :src="previewImgUrl" alt="" />
  68. </el-dialog>
  69. </div>
  70. </template>
  71. <script>
  72. import logo from '@/assets/pdf.png'
  73. export default {
  74. name: 'FileUpload',
  75. props: {
  76. value: {
  77. type: [String, Array],
  78. default: ''
  79. },
  80. // 上传的地址
  81. action: {
  82. type: String,
  83. default: 'https://ht.9026.com/api/File',
  84. },
  85. // 设置上传的请求头部
  86. headers: {
  87. type: Object,
  88. default: () => {
  89. return {}
  90. },
  91. },
  92. // 上传文件大小限制, 默认 50M,单位M
  93. size: {
  94. type: [Number, String],
  95. default: 50,
  96. },
  97. // 文件上传格式, 默认jpeg, png,jpg
  98. accept: {
  99. type: String,
  100. default: 'image/jpeg,image/png',
  101. },
  102. // 是否显示删除操作按钮
  103. deleted: {
  104. type: Boolean,
  105. default: true,
  106. },
  107. // 是否显示预览操作按钮
  108. preview: {
  109. type: Boolean,
  110. default: true,
  111. },
  112. // 是否显示下载操作按钮
  113. download: {
  114. type: Boolean,
  115. default: true,
  116. },
  117. // 上传文件个数限制,默认0 不限制
  118. limit: {
  119. type: [Number, String],
  120. default: 0,
  121. },
  122. },
  123. data() {
  124. return {
  125. fileList: [], // 默认文件列表
  126. hideUpload: false, // 超出限制掩藏上传按钮
  127. uploading: false, // 是否上传中,上传时隐藏上传按钮
  128. previewImgUrl: '', // 预览图片地址
  129. previewVisible: false, // 是否显示预览
  130. pdf: logo,
  131. files: [], // 文件url数组
  132. }
  133. },
  134. watch:{
  135. value: {
  136. handler(val, old){
  137. console.log('FileUpload=', val)
  138. if(val){
  139. this.files = val
  140. this.fileList = [] // 先清空
  141. for(var i=0; i<val.length;i++){
  142. this.fileList.push({
  143. url: val[i] // 转化
  144. })
  145. }
  146. this.handleChange()
  147. }
  148. },
  149. deep: true,
  150. immediate: true // 避免在子组件中监听失效
  151. }
  152. },
  153. methods: {
  154. emitInput() {
  155. this.$emit('input', this.files)
  156. },
  157. // 判断是否pdf
  158. isPDF(url) {
  159. if(!url){
  160. return false
  161. }
  162. const fileType = ['pdf']
  163. const index = url.lastIndexOf('.')
  164. const type = url.substr(index + 1)
  165. return fileType.indexOf(type) > -1
  166. },
  167. // 文件上传成功
  168. handleImageSuccess(res) {
  169. if (res.code === 200) {
  170. console.log("上传成功")
  171. this.files.push(res.data.file)
  172. this.emitInput()
  173. } else {
  174. this.$message.error('文件上传失败')
  175. }
  176. },
  177. // 上传前文件大小判断
  178. beforeUpload(file) {
  179. const { size } = this
  180. const overSize = size > 0 && file.size < 1024 * 1024 * size
  181. if (!overSize) this.$message.error(`上传文件大小不能超过 ${size}MB!`)
  182. this.uploading = overSize // 是否上传中
  183. return overSize
  184. },
  185. // 上传出错返回
  186. handleError(event, file, fileList) {
  187. console.log(event, file, fileList, 'error')
  188. this.$message.error('服务出错,上传失败!')
  189. this.handleChange()
  190. },
  191. // 删除图片
  192. async handleRemove(file) {
  193. console.log("删除文件")
  194. this.$confirm(`确认删除文件?`, '提示', {
  195. confirmButtonText: '确定',
  196. cancelButtonText: '取消',
  197. type: 'warning'
  198. }).then(async () => {
  199. const { fileList } = this
  200. this.files = this.files.filter((v) => v !== file.url)
  201. this.emitInput()
  202. }).catch(()=>{})
  203. },
  204. // 图片预览
  205. handlePreview(file) {
  206. if(this.isPDF(file.url)){
  207. window.open(file.url, "_blank");
  208. } else {
  209. this.previewImgUrl = file.url
  210. this.previewVisible = true
  211. }
  212. },
  213. handleChange(file, list) {
  214. const { limit, fileList } = this
  215. if (limit > 0 && fileList.length >= limit) this.hideUpload = true
  216. else this.hideUpload = false
  217. this.uploading = false
  218. },
  219. handleDownload(file) {
  220. window.open(file.url, "_blank");
  221. /*const a = document.createElement('a')
  222. a.href = file.url
  223. a.click() // 模拟点击事件,实现图片文件的同源下载
  224. */
  225. },
  226. },
  227. }
  228. </script>
  229. <style lang="scss" scoped>
  230. .hideUpload .el-upload--picture-card {
  231. display: none;
  232. }
  233. .el-upload-list--picture-card .uploading.el-upload-list__item-actions {
  234. opacity: 1;
  235. }
  236. /*添加、删除文件时去掉动画过渡*/
  237. .el-upload-list__item {
  238. transition: none !important;
  239. }
  240. .el-upload-list--picture-card .el-upload-list__item-thumbnail {
  241. width: 148px;
  242. height: 148px;
  243. }
  244. .el-upload-list--picture-card .el-upload-list__item {
  245. background-color: inherit;
  246. border: none;
  247. width: 148px;
  248. height: 148px;
  249. }
  250. </style>