di-upload.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <template>
  2. <u-upload
  3. class="di-upload"
  4. :max-size="uploadConfig.maxSize"
  5. :max-count="uploadConfig.limitCount"
  6. :upload-text="uploadConfig.uploadText"
  7. :width="uploadConfig.width"
  8. :height="uploadConfig.height"
  9. name="file"
  10. :show-progress="uploadConfig.showProgress"
  11. :deletable="uploadConfig.deletable"
  12. :action="uploadAction"
  13. @on-success="handleSuccess"
  14. @on-remove="handleRemove"
  15. :form-data="uploadFormData"
  16. :header="header"
  17. :file-list="tempFileList"
  18. >
  19. </u-upload>
  20. </template>
  21. <script>
  22. /**
  23. * di-upload 上传组件
  24. * @description 上传组件,基于u-upload,适配form
  25. * @property {String} value 上传后的后端返回地址,支持v-model双向绑定
  26. * @property {String} action 向后端发送的请求地址,默认'/uploadFile/upload/dto'
  27. * @property {String} rel-obj-type 绑定的业务对象名,自动设置到form-data对象中
  28. * @property {String} rel-obj-field 绑定业务对象的属性,自动设置到form-data对象中
  29. * @property {Object} form-data 提交的form-data,优先级最低,单独的属性设置会覆盖对象的配置
  30. * @property {Array} file-list 文件存储位置
  31. * @property {String} limit-count 上传数量限制,默认1,自动设置到config对象中
  32. * @property {Boolean} show-progress 是否显示进度条,默认true,自动设置到config对象中
  33. * @property {String} max-size 选择单个文件的最大大小,单位B(byte),默认不限制,自动设置到config对象中
  34. * @property {Boolean} deletable 是否显示删除图片的按钮,默认true,自动设置到config对象中
  35. * @property {String} width 图片预览区域和添加图片按钮的宽度(单位:rpx),默认200 ,自动设置到config对象中
  36. * @property {String} height 图片预览区域和添加图片按钮的高度(单位:rpx) ,默认200,自动设置到config对象中
  37. * @property {String} upload-text 上传框里面的文本 ,默认 ‘上传’,自动设置到config对象中
  38. * @property {Object} config 上传组件配置,优先级最低,单独的属性设置会覆盖对象的配置
  39. */
  40. import Emitter from '../../uview-ui/libs/util/emitter.js';
  41. export default {
  42. mixins: [Emitter],
  43. computed: {
  44. header() {
  45. return {
  46. authtoken: uni.getStorageSync('authtoken') || ''
  47. }
  48. },
  49. // 更新回显
  50. tempFileList: {
  51. get() {
  52. return this.fileList
  53. },
  54. set() {}
  55. },
  56. uploadFormData() {
  57. let tempFormData = this.formData || {}
  58. tempFormData.relObjType = this.relObjType
  59. tempFormData.relObjField = this.relObjField
  60. return tempFormData
  61. },
  62. uploadConfig() {
  63. let tempConfig = this.config || {}
  64. tempConfig.maxSize = this.maxSize
  65. tempConfig.limitCount = this.limitCount
  66. tempConfig.uploadText = this.uploadText
  67. tempConfig.width = this.width
  68. tempConfig.height = this.height
  69. tempConfig.showProgress = this.showProgress
  70. tempConfig.deletable = this.deletable
  71. return tempConfig
  72. },
  73. uploadAction() {
  74. return `${this.$cons.host()}${this.action}`
  75. }
  76. },
  77. methods: {
  78. /**
  79. * 上传成功触发
  80. * @param {Object} data
  81. * @param {Object} index
  82. * @param {Object} lists
  83. * @param {Object} name
  84. */
  85. handleSuccess(data, index, lists, name) {
  86. lists.length = 0
  87. if (this.limitCount === 1) {
  88. this.fileList.length = 0
  89. }
  90. this.fileList.push(this.fileFormatter(data.data))
  91. console.log('add end', this.fileList)
  92. this.$emit('update:fileList', this.fileList)
  93. this.$forceUpdate()
  94. this.handleInputEvent()
  95. },
  96. /**
  97. * 删除图片触发
  98. * @param {Object} index
  99. * @param {Object} lists
  100. * @param {Object} name
  101. */
  102. handleRemove(index, lists, name) {
  103. const newFileList = this.fileList.slice()
  104. newFileList.splice(index, 1)
  105. this.fileList.length = 0
  106. this.fileList.push(...newFileList)
  107. this.$emit('update:fileList', this.fileList)
  108. console.log('remove end', this.fileList)
  109. this.handleInputEvent()
  110. },
  111. /**
  112. * 文件转化
  113. *
  114. * @param {Object} data
  115. */
  116. fileFormatter(data) {
  117. return {
  118. uid: data.uuid,
  119. filePath: data.accessUrl,
  120. url: `${this.$cons.host()}${data.accessUrl}/image`
  121. }
  122. },
  123. /**
  124. * 发送input消息
  125. * 过一个生命周期再发送事件给u-form-item,否则this.$emit('input')更新了父组件的值
  126. * 但是微信小程序上 尚未更新到u-form-item,导致获取的值为空
  127. */
  128. handleInputEvent() {
  129. const value = this.fileList.map(file => file.filePath).join(',')
  130. this.$emit('input', value)
  131. this.$nextTick(function(){
  132. // 将当前的值发送到 u-form-item 进行校验
  133. this.dispatch('u-form-item', 'on-form-change', value);
  134. })
  135. }
  136. },
  137. props: {
  138. value: {
  139. type: String,
  140. require: true
  141. },
  142. action: {
  143. type: String,
  144. default: '/uploadFile/upload/dto'
  145. },
  146. relObjType: {
  147. type: String,
  148. required: true
  149. },
  150. relObjField: {
  151. type: String,
  152. required: true
  153. },
  154. // 回显操作
  155. fileList: {
  156. type: Array,
  157. require: true
  158. },
  159. limitCount: {
  160. type: Number,
  161. default: 1
  162. },
  163. maxSize: {
  164. type: Number,
  165. default: Number.MAX_VALUE
  166. },
  167. height: {
  168. type: [Number, String],
  169. default: 200
  170. },
  171. width: {
  172. type: [Number, String],
  173. default: 200
  174. },
  175. deletable: {
  176. type: Boolean,
  177. default: true
  178. },
  179. showProgress: {
  180. type: Boolean,
  181. default: true
  182. },
  183. uploadText: {
  184. type: String,
  185. default: '上传'
  186. },
  187. formData: {
  188. type: Object,
  189. default: () => {}
  190. },
  191. config: {
  192. type: Object,
  193. default: () => {}
  194. }
  195. }
  196. }
  197. </script>
  198. <style lang="scss" scoped>
  199. .u-upload {
  200. /deep/ .u-list-item {
  201. display: flex;
  202. }
  203. }
  204. </style>