index.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import { VantComponent } from '../common/component';
  2. import { isImageFile, chooseFile, isVideoFile } from './utils';
  3. import { chooseImageProps, chooseVideoProps } from './shared';
  4. import { isBoolean, isPromise } from '../common/validator';
  5. VantComponent({
  6. props: Object.assign(
  7. Object.assign(
  8. {
  9. disabled: Boolean,
  10. multiple: Boolean,
  11. uploadText: String,
  12. useBeforeRead: Boolean,
  13. afterRead: null,
  14. beforeRead: null,
  15. previewSize: {
  16. type: null,
  17. value: 80,
  18. },
  19. name: {
  20. type: [Number, String],
  21. value: '',
  22. },
  23. accept: {
  24. type: String,
  25. value: 'image',
  26. },
  27. fileList: {
  28. type: Array,
  29. value: [],
  30. observer: 'formatFileList',
  31. },
  32. maxSize: {
  33. type: Number,
  34. value: Number.MAX_VALUE,
  35. },
  36. maxCount: {
  37. type: Number,
  38. value: 100,
  39. },
  40. deletable: {
  41. type: Boolean,
  42. value: true,
  43. },
  44. showUpload: {
  45. type: Boolean,
  46. value: true,
  47. },
  48. previewImage: {
  49. type: Boolean,
  50. value: true,
  51. },
  52. previewFullImage: {
  53. type: Boolean,
  54. value: true,
  55. },
  56. imageFit: {
  57. type: String,
  58. value: 'scaleToFill',
  59. },
  60. uploadIcon: {
  61. type: String,
  62. value: 'photograph',
  63. },
  64. },
  65. chooseImageProps
  66. ),
  67. chooseVideoProps
  68. ),
  69. data: {
  70. lists: [],
  71. isInCount: true,
  72. },
  73. methods: {
  74. formatFileList() {
  75. const { fileList = [], maxCount } = this.data;
  76. const lists = fileList.map((item) =>
  77. Object.assign(Object.assign({}, item), {
  78. isImage: isImageFile(item),
  79. isVideo: isVideoFile(item),
  80. deletable: isBoolean(item.deletable) ? item.deletable : true,
  81. })
  82. );
  83. console.log(lists);
  84. this.setData({ lists, isInCount: lists.length < maxCount });
  85. },
  86. getDetail(index) {
  87. return {
  88. name: this.data.name,
  89. index: index == null ? this.data.fileList.length : index,
  90. };
  91. },
  92. startUpload() {
  93. const { maxCount, multiple, accept, lists, disabled } = this.data;
  94. if (disabled) return;
  95. chooseFile(
  96. Object.assign(Object.assign({}, this.data), {
  97. maxCount: maxCount - lists.length,
  98. })
  99. )
  100. .then((res) => {
  101. console.log(res);
  102. this.onBeforeRead(multiple ? res : res[0]);
  103. })
  104. .catch((error) => {
  105. this.$emit('error', error);
  106. });
  107. },
  108. onBeforeRead(file) {
  109. const { beforeRead, useBeforeRead } = this.data;
  110. let res = true;
  111. if (typeof beforeRead === 'function') {
  112. res = beforeRead(file, this.getDetail());
  113. }
  114. if (useBeforeRead) {
  115. res = new Promise((resolve, reject) => {
  116. this.$emit(
  117. 'before-read',
  118. Object.assign(Object.assign({ file }, this.getDetail()), {
  119. callback: (ok) => {
  120. ok ? resolve() : reject();
  121. },
  122. })
  123. );
  124. });
  125. }
  126. if (!res) {
  127. return;
  128. }
  129. if (isPromise(res)) {
  130. res.then((data) => this.onAfterRead(data || file));
  131. } else {
  132. this.onAfterRead(file);
  133. }
  134. },
  135. onAfterRead(file) {
  136. const { maxSize, afterRead } = this.data;
  137. const oversize = Array.isArray(file)
  138. ? file.some((item) => item.size > maxSize)
  139. : file.size > maxSize;
  140. if (oversize) {
  141. this.$emit('oversize', Object.assign({ file }, this.getDetail()));
  142. return;
  143. }
  144. if (typeof afterRead === 'function') {
  145. afterRead(file, this.getDetail());
  146. }
  147. this.$emit('after-read', Object.assign({ file }, this.getDetail()));
  148. },
  149. deleteItem(event) {
  150. const { index } = event.currentTarget.dataset;
  151. this.$emit(
  152. 'delete',
  153. Object.assign(Object.assign({}, this.getDetail(index)), {
  154. file: this.data.fileList[index],
  155. })
  156. );
  157. },
  158. onPreviewImage(event) {
  159. if (!this.data.previewFullImage) return;
  160. const { index } = event.currentTarget.dataset;
  161. const { lists } = this.data;
  162. const item = lists[index];
  163. wx.previewImage({
  164. urls: lists.filter((item) => isImageFile(item)).map((item) => item.url),
  165. current: item.url,
  166. fail() {
  167. wx.showToast({ title: '预览图片失败', icon: 'none' });
  168. },
  169. });
  170. },
  171. onPreviewVideo(event) {
  172. if (!this.data.previewFullImage) return;
  173. const { index } = event.currentTarget.dataset;
  174. const { lists } = this.data;
  175. wx.previewMedia({
  176. sources: lists
  177. .filter((item) => isVideoFile(item))
  178. .map((item) =>
  179. Object.assign(Object.assign({}, item), { type: 'video' })
  180. ),
  181. current: index,
  182. fail() {
  183. wx.showToast({ title: '预览视频失败', icon: 'none' });
  184. },
  185. });
  186. },
  187. onClickPreview(event) {
  188. const { index } = event.currentTarget.dataset;
  189. const item = this.data.lists[index];
  190. this.$emit(
  191. 'click-preview',
  192. Object.assign(Object.assign({}, item), this.getDetail(index))
  193. );
  194. },
  195. },
  196. });