3
3
Describe: 多图片上传组件, 附有预览, 排序, 验证等功能
4
4
5
5
todo: 支持 before-upload
6
- todo: 图像验证支持验证是否是动图
7
6
todo: 文档编写
8
7
todo: jsDoc 编写
9
8
todo: 文件判断使用 serveWorker 优化性能
@@ -98,7 +97,8 @@ import {
98
97
} from ' ./utils'
99
98
100
99
/**
101
- * @typedef {Object<string, number, any>} LocalFileInfo 本地图像通过验证后构造的信息对象
100
+ * 本地图像通过验证后构造的信息对象
101
+ * @typedef {Object<string, number, any>} LocalFileInfo
102
102
* @property {string} localSrc 本地图像预览地址
103
103
* @property {File} file 本地图像文件
104
104
* @property {number} width 宽
@@ -110,15 +110,17 @@ import {
110
110
*/
111
111
112
112
/**
113
- * @typedef {Object<string, number, any>} PreviewItem 本地图像通过验证后构造的信息对象
114
- * @property {string} localSrc 本地图像预览地址
115
- * @property {File} file 本地图像文件
116
- * @property {number} width 宽
113
+ * 返回数据对象
114
+ * @typedef {Object<string, number>} ReturnItem
115
+ * @property {number|string} id 本地图像预览地址
116
+ * @property {number|string} imgId 宽
117
+ * @property {string} src 文件相对路径
118
+ * @property {string} display 文件完整路径
117
119
* @property {number} height 高
118
- * @property {string} name 文件名
119
- * @property {number} size 文件大小
120
- * @property {string} type 文件的媒体类型 (MIME)
121
- * @property {Date} lastModified 文件最后修改时间
120
+ * @property {number} width 宽
121
+ * @property {string} fileName 文件名
122
+ * @property {string} fileType 文件的媒体类型 (MIME), 针对部分文件类型做了检测
123
+ * @property {boolean} isAnimated 是否是动态图, 如果不进行检测则为 null
122
124
*/
123
125
124
126
const ONE_KB = 1024
@@ -285,12 +287,12 @@ export default {
285
287
},
286
288
/** 上传前插入方法, 属于高级用法 */
287
289
beforeUpload: {
288
- type: Promise ,
290
+ type: Function ,
289
291
default: null ,
290
292
},
291
293
/** 重写上传方法, 如果重写则覆盖组件内上传方法 */
292
294
remoteFuc: {
293
- type: [ Function , Promise ] ,
295
+ type: Function ,
294
296
default: null ,
295
297
},
296
298
/** 图像显示模式 */
@@ -536,38 +538,70 @@ export default {
536
538
}
537
539
// eslint-disable-next-line
538
540
item .loading = true
539
- // 如果是用户自定义方法
540
- // 出于简化 api 的考虑, 只允许单个文件上传
541
- if ( this . remoteFuc ) {
542
- // 回调函数模式
543
- if ( typeof this . remoteFuc === ' function ' ) {
544
- return new Promise (( resolve ) => {
545
- const a = this . remoteFuc ( item . file , ( data ) => {
546
- reduceResult (item, data )
547
- if ( ! data) {
548
- this . $message . error ( ' 执行自定义上传出错 ' )
549
- resolve ( false )
550
- } else {
551
- resolve (item)
552
- }
553
- })
541
+ if ( this . beforeUpload && typeof this . beforeUpload === ' function ' ) {
542
+ if ( typeof this . beforeUpload === ' function ' ) {
543
+ const result = await new Promise (( resolve ) => {
544
+ let a
545
+ try {
546
+ a = this . beforeUpload (item, ( data ) => {
547
+ if ( ! data) {
548
+ resolve ( false )
549
+ } else {
550
+ resolve ( true )
551
+ }
552
+ })
553
+ } catch (err) {
554
+ resolve ( false )
555
+ }
554
556
// promise 模式
555
557
if (a != null && typeof a .then === ' function' ) {
556
558
a .then ((remoteData ) => {
557
- reduceResult (item, remoteData)
558
559
if (! remoteData) {
559
560
resolve (false )
560
561
}
561
- resolve (item )
562
+ resolve (true )
562
563
})
563
564
}
564
565
})
566
+ if (! result) {
567
+ reduceResult (item, false )
568
+ return false
569
+ }
565
570
}
566
571
567
572
// 除 promise 和 函数回调外其他形式都不支持
568
573
this .$message .error (' 执行自定义上传出错, 检查远程方法是否是promise或者函数' )
569
574
return false
570
575
}
576
+ // 如果是用户自定义方法
577
+ // 出于简化 api 的考虑, 只允许单个文件上传
578
+ if (this .remoteFuc && typeof this .remoteFuc === ' function' ) {
579
+ return new Promise ((resolve ) => {
580
+ const a = this .remoteFuc (item .file , (data ) => {
581
+ reduceResult (item, data)
582
+ if (! data) {
583
+ this .$message .error (' 执行自定义上传出错' )
584
+ resolve (false )
585
+ } else {
586
+ resolve (item)
587
+ }
588
+ })
589
+ // promise 模式
590
+ if (a != null && typeof a .then === ' function' ) {
591
+ a .then ((remoteData ) => {
592
+ reduceResult (item, remoteData)
593
+ if (! remoteData) {
594
+ resolve (false )
595
+ }
596
+ resolve (item)
597
+ })
598
+ }
599
+ })
600
+
601
+ // 除 promise 和 函数回调外其他形式都不支持
602
+ this .$message .error (' 执行自定义上传出错, 检查远程方法是否是promise或者函数' )
603
+ return false
604
+ }
571
605
572
606
// 使用内置上传
573
607
return new Promise ((resolve ) => {
@@ -623,12 +657,24 @@ export default {
623
657
}
624
658
625
659
// 如无错误, 表示图像都以上传, 开始构造数据
626
- const result = imgInfoList .map (item => ({
627
- id: item .status === ' new' ? ' ' : item .id ,
628
- imgId: item .imgId ,
629
- src: item .src ,
630
- display: item .display ,
631
- }))
660
+ /**
661
+ * @type {array<ReturnItem>}
662
+ */
663
+ const result = imgInfoList .map ((item ) => {
664
+ /** @type {ReturnItem} */
665
+ const val = {
666
+ id: item .status === ' new' ? ' ' : item .id ,
667
+ imgId: item .imgId ,
668
+ src: item .src ,
669
+ display: item .display ,
670
+ width: item .width ,
671
+ height: item .height ,
672
+ fileName: item .name ,
673
+ fileType: item .type ,
674
+ isAnimated: item .isAnimated ,
675
+ }
676
+ return val
677
+ })
632
678
// 获取数据成功后发出
633
679
this .$emit (' upload' , result)
634
680
return result
@@ -850,7 +896,7 @@ export default {
850
896
}
851
897
}
852
898
} else {
853
- const empty = max - itemList .length + 1
899
+ const empty = max - itemList .length
854
900
if (max && l > empty) {
855
901
l = empty
856
902
}
@@ -945,7 +991,7 @@ export default {
945
991
image .src = localSrc
946
992
image .onload = () => {
947
993
/**
948
- * @type LocalFileInfo
994
+ * @type { LocalFileInfo}
949
995
*/
950
996
const localFileInfo = {
951
997
localSrc,
@@ -958,7 +1004,6 @@ export default {
958
1004
lastModified: file .lastModified ,
959
1005
isAnimated,
960
1006
}
961
- console .log (localFileInfo)
962
1007
resolve (localFileInfo)
963
1008
image = null
964
1009
}
0 commit comments