uploadImg.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <!--
  2. * @Description: 对上传图片组件进行封装
  3. * @Author: kcz
  4. * @Date: 2020-03-17 12:53:50
  5. * @LastEditors: kcz
  6. * @LastEditTime: 2021-05-05 12:12:39
  7. -->
  8. <template>
  9. <div
  10. :style="{ width: record.options.width }"
  11. class="upload-img-box-9136076486841527"
  12. >
  13. <a-upload
  14. :name="config.uploadImageName || record.options.fileName"
  15. :headers="config.uploadImageHeaders || record.options.headers"
  16. :data="config.uploadImageData || optionsData"
  17. :action="config.uploadImage || record.options.action"
  18. :multiple="record.options.multiple"
  19. :listType="record.options.listType"
  20. :disabled="record.options.disabled || parentDisabled"
  21. :fileList="fileList"
  22. accept="image/gif, image/jpeg, image/png"
  23. @change="handleChange"
  24. @preview="handlePreview"
  25. :remove="remove"
  26. :beforeUpload="beforeUpload"
  27. >
  28. <a-button
  29. v-if="
  30. record.options.listType !== 'picture-card' &&
  31. fileList.length < record.options.limit
  32. "
  33. :disabled="record.options.disabled || parentDisabled"
  34. >
  35. <a-icon type="upload" /> {{ record.options.placeholder }}
  36. </a-button>
  37. <div
  38. v-if="
  39. record.options.listType === 'picture-card' &&
  40. fileList.length < record.options.limit
  41. "
  42. :disabled="record.options.disabled || parentDisabled"
  43. >
  44. <a-icon type="plus" />
  45. <div class="ant-upload-text">{{ record.options.placeholder }}</div>
  46. </div>
  47. </a-upload>
  48. <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
  49. <img alt="example" style="width: 100%" :src="previewImageUrl" />
  50. </a-modal>
  51. </div>
  52. </template>
  53. <script>
  54. /*
  55. * author kcz
  56. * date 2019-12-31
  57. * description 上传图片组件
  58. */
  59. export default {
  60. name: "KUploadImg",
  61. // eslint-disable-next-line vue/require-prop-types
  62. props: ["record", "value", "config", "parentDisabled"],
  63. data() {
  64. return {
  65. fileList: [],
  66. previewVisible: false,
  67. previewImageUrl: ""
  68. };
  69. },
  70. watch: {
  71. value: {
  72. // value 需要深度监听及默认先执行handler函数
  73. handler(val) {
  74. if (val) {
  75. this.setFileList();
  76. }
  77. },
  78. immediate: true,
  79. deep: true
  80. }
  81. },
  82. computed: {
  83. optionsData() {
  84. try {
  85. return JSON.parse(this.record.options.data);
  86. } catch (err) {
  87. console.error(err);
  88. return {};
  89. }
  90. }
  91. },
  92. methods: {
  93. setFileList() {
  94. // 当传入value改变时,fileList也要改变
  95. // 如果传入的值为字符串,则转成json
  96. if (typeof this.value === "string") {
  97. this.fileList = JSON.parse(this.value);
  98. // 将转好的json覆盖组件默认值的字符串
  99. this.handleSelectChange();
  100. } else {
  101. this.fileList = this.value;
  102. }
  103. },
  104. handleSelectChange() {
  105. setTimeout(() => {
  106. const arr = this.fileList.map(item => {
  107. if (typeof item.response !== "undefined") {
  108. const res = item.response;
  109. return {
  110. type: "img",
  111. name: item.name,
  112. status: item.status,
  113. uid: item.uid,
  114. url: res.data.url || ""
  115. };
  116. } else {
  117. return {
  118. type: "img",
  119. name: item.name,
  120. status: item.status,
  121. uid: item.uid,
  122. url: item.url || ""
  123. };
  124. }
  125. });
  126. this.$emit("change", arr);
  127. this.$emit("input", arr);
  128. }, 10);
  129. },
  130. handlePreview(file) {
  131. // 预览图片
  132. this.previewImageUrl = file.url || file.thumbUrl;
  133. this.previewVisible = true;
  134. },
  135. handleCancel() {
  136. // 取消操作
  137. this.previewVisible = false;
  138. },
  139. remove() {
  140. this.handleSelectChange();
  141. },
  142. beforeUpload(e, files) {
  143. if (files.length + this.fileList.length > this.record.options.limit) {
  144. this.$message.warning(`最大上传数量为${this.record.options.limit}`);
  145. files.splice(this.record.options.limit - this.fileList.length);
  146. }
  147. },
  148. handleChange(info) {
  149. // 上传数据改变时
  150. this.fileList = info.fileList;
  151. if (info.file.status === "done") {
  152. const res = info.file.response;
  153. if (res.code === 0) {
  154. this.handleSelectChange();
  155. } else {
  156. this.fileList.pop();
  157. this.$message.error(`图片上传失败`);
  158. }
  159. } else if (info.file.status === "error") {
  160. this.$message.error(`图片上传失败`);
  161. }
  162. }
  163. }
  164. };
  165. </script>
  166. <style lang="less">
  167. .upload-img-box-9136076486841527 {
  168. /* you can make up upload button and sample style by using stylesheets */
  169. .ant-upload-select-picture-card i {
  170. font-size: 32px;
  171. color: #999;
  172. }
  173. .ant-upload-select-picture-card .ant-upload-text {
  174. margin-top: 8px;
  175. color: #666;
  176. }
  177. }
  178. </style>