imageUpload.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <template>
  2. <!-- 图片上传 -->
  3. <view class="image-upload">
  4. <u-upload v-on="_listeners" v-bind="_attrs">
  5. <slot></slot>
  6. </u-upload>
  7. </view>
  8. </template>
  9. <script>
  10. import { uploadFile } from '@/api/com';
  11. export default {
  12. name: 'imageUpload',
  13. inheritAttrs: false,
  14. model: {
  15. prop: 'value',
  16. event: 'change',
  17. },
  18. props: {
  19. value: {
  20. type: Array,
  21. default: () => [],
  22. },
  23. },
  24. watch: {
  25. value: {
  26. handler(list) {
  27. this.fileList = list;
  28. },
  29. immediate: true,
  30. },
  31. },
  32. computed: {
  33. _attrs() {
  34. return {
  35. ...this.$attrs,
  36. fileList: this.fileList,
  37. maxCount: this.$attrs.maxCount || 20,
  38. };
  39. },
  40. _listeners() {
  41. return {
  42. ...this.$listeners,
  43. afterRead: this.afterPic,
  44. delete: this.deletePic,
  45. };
  46. },
  47. },
  48. data() {
  49. return {
  50. fileList: [],
  51. };
  52. },
  53. methods: {
  54. deepUpload(fileData) {
  55. // 多选上传
  56. let idx = 0;
  57. const upload = async () => {
  58. try {
  59. if (fileData.length === idx) {
  60. return;
  61. }
  62. const file = fileData[idx];
  63. idx++;
  64. this.fileList.push({
  65. ...file,
  66. status: 'uploading',
  67. message: '上传中',
  68. });
  69. const fileIdx = this.fileList.length - 1;
  70. const { data } = await uploadFile(file.url);
  71. // 上传成功 todo 这里是把旧的删除替换新的 http_url 并改变status
  72. this.fileList.splice(fileIdx, 1, {
  73. status: 'success',
  74. message: '',
  75. url: data.http_url,
  76. noPrefixUrl: data.url, // 没有前缀的
  77. });
  78. this.$emit('change', this.fileList); // 改变父组件的 value
  79. upload(); // 递归 一个一个上传
  80. } catch (e) {
  81. // 上传失败
  82. this.fileList.splice(this.fileList.length - 1, 1); // 因为在请求接口就push了
  83. this.$emit('change', this.fileList); // 改变父组件的 value
  84. console.error(e);
  85. }
  86. };
  87. upload();
  88. },
  89. async singleUpload(file) {
  90. //单多选上传
  91. try {
  92. this.fileList.push({
  93. ...file,
  94. status: 'uploading',
  95. message: '上传中',
  96. });
  97. const fileIdx = this.fileList.length - 1;
  98. const { data } = await uploadFile(file.url);
  99. // 上传成功
  100. this.fileList.splice(fileIdx, 1, {
  101. status: 'success',
  102. message: '',
  103. url: data.http_url,
  104. noPrefixUrl: data.url, // 没有前缀的
  105. });
  106. this.$emit('change', this.fileList); // 改变父组件的 value
  107. } catch (e) {
  108. // 上传失败
  109. this.fileList.splice(this.fileList.length - 1, 1);
  110. this.$emit('change', this.fileList); // 改变父组件的 value
  111. console.error(e);
  112. }
  113. },
  114. async afterPic(e) {
  115. if (this.$listeners.afterRead) {
  116. // 外部自定义
  117. this.$emit('afterRead', e);
  118. return;
  119. }
  120. const { file } = e;
  121. // 开启了多选上传图片 {Array} file
  122. this.$attrs.multiple && this.deepUpload(file); // 递归 一个一个上传 (避免某一个失败,删除file的问题)
  123. // 没有开启多选上传
  124. !this.$attrs.multiple && this.singleUpload(file);
  125. },
  126. deletePic(e) {
  127. if (this.$listeners.delete) {
  128. this.$emit('delete', e);
  129. return;
  130. }
  131. this.fileList.splice(e.index, 1); // 删除
  132. this.$emit('change', this.fileList); // 改变父组件的 value
  133. },
  134. },
  135. };
  136. </script>
  137. <style scoped lang="scss"></style>