Skip to content

Commit e69e9b0

Browse files
committed
feat(imgUpload): 支持更全面的返回值, 支持 上传前自定义校验
1 parent 3fa09ca commit e69e9b0

File tree

3 files changed

+117
-56
lines changed

3 files changed

+117
-56
lines changed

src/components/base/upload-imgs/README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,24 @@ export default {
4646

4747
## props
4848

49-
| 参数 | 类型 | 默认值 | 说明 |
50-
| :------------: | :-----------: | :------: | :------------------------: |
51-
| value | Array | [] | 初始化数据 |
52-
| auto-upload | Boolean | true | 新增图片是是否自动上传 |
53-
| disabled | Boolean | false | 是否禁用 |
54-
| preview | Boolean | true | 是否可预览 |
55-
| multiple | Boolean | false | 是否可以一次多选 |
56-
| min-num | Number | 0 | 最少图片数量 |
57-
| max-num | Number | 0 | 最多图片数量, 0 表示无限制 |
58-
| before-upload | Function | null | 上传前自定义校验函数 |
59-
| remote-fuc | Function | null | 重写远程方法 |
60-
| sortable | Boolean | false | 是否可排序 |
61-
| accept | String | image/\* | 运行上传的类型 |
62-
| animated-check | Boolean | false | 是否需要检测是否是动图 |
63-
| rules | Object | {} | 图像规则 |
64-
| fit | String | contain | 图像显示形式 |
65-
| width | Nulber/String | 200 | 宽度 |
66-
| height | Number/String | 200 | 高度 |
49+
| 参数 | 类型 | 默认值 | 说明 |
50+
| :------------: | :-----------: | :------: | :----------------------------------------------------------------------------------------: |
51+
| value | Array | [] | 初始化数据 |
52+
| auto-upload | Boolean | true | 新增图片是是否自动上传 |
53+
| disabled | Boolean | false | 是否禁用 |
54+
| preview | Boolean | true | 是否可预览 |
55+
| multiple | Boolean | false | 是否可以一次多选 |
56+
| min-num | Number | 0 | 最少图片数量 |
57+
| max-num | Number | 0 | 最多图片数量, 0 表示无限制 |
58+
| before-upload | Function | null | 上传前自定义校验函数, 返回 true 表示校验成功, 否则校验失败不进行后续上传, 支持返回 Promise |
59+
| remote-fuc | Function | null | 重写远程方法, 支持返回 Promise |
60+
| sortable | Boolean | false | 是否可排序 |
61+
| accept | String | image/\* | 运行上传的类型 |
62+
| animated-check | Boolean | false | 是否需要检测是否是动图 |
63+
| rules | Object | {} | 图像规则 |
64+
| fit | String | contain | 图像显示形式 |
65+
| width | Nulber/String | 200 | 宽度 |
66+
| height | Number/String | 200 | 高度 |
6767

6868
图像验证规则属性 rule 支持的验证规则有:
6969

src/components/base/upload-imgs/index.vue

Lines changed: 83 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
Describe: 多图片上传组件, 附有预览, 排序, 验证等功能
44
55
todo: 支持 before-upload
6-
todo: 图像验证支持验证是否是动图
76
todo: 文档编写
87
todo: jsDoc 编写
98
todo: 文件判断使用 serveWorker 优化性能
@@ -98,7 +97,8 @@ import {
9897
} from './utils'
9998
10099
/**
101-
* @typedef {Object<string, number, any>} LocalFileInfo 本地图像通过验证后构造的信息对象
100+
* 本地图像通过验证后构造的信息对象
101+
* @typedef {Object<string, number, any>} LocalFileInfo
102102
* @property {string} localSrc 本地图像预览地址
103103
* @property {File} file 本地图像文件
104104
* @property {number} width
@@ -110,15 +110,17 @@ import {
110110
*/
111111
112112
/**
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 文件完整路径
117119
* @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
122124
*/
123125
124126
const ONE_KB = 1024
@@ -285,12 +287,12 @@ export default {
285287
},
286288
/** 上传前插入方法, 属于高级用法 */
287289
beforeUpload: {
288-
type: Promise,
290+
type: Function,
289291
default: null,
290292
},
291293
/** 重写上传方法, 如果重写则覆盖组件内上传方法 */
292294
remoteFuc: {
293-
type: [Function, Promise],
295+
type: Function,
294296
default: null,
295297
},
296298
/** 图像显示模式 */
@@ -536,38 +538,70 @@ export default {
536538
}
537539
// eslint-disable-next-line
538540
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+
}
554556
// promise 模式
555557
if (a != null && typeof a.then === 'function') {
556558
a.then((remoteData) => {
557-
reduceResult(item, remoteData)
558559
if (!remoteData) {
559560
resolve(false)
560561
}
561-
resolve(item)
562+
resolve(true)
562563
})
563564
}
564565
})
566+
if (!result) {
567+
reduceResult(item, false)
568+
return false
569+
}
565570
}
566571
567572
// 除 promise 和 函数回调外其他形式都不支持
568573
this.$message.error('执行自定义上传出错, 检查远程方法是否是promise或者函数')
569574
return false
570575
}
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+
}
571605
572606
// 使用内置上传
573607
return new Promise((resolve) => {
@@ -623,12 +657,24 @@ export default {
623657
}
624658
625659
// 如无错误, 表示图像都以上传, 开始构造数据
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+
})
632678
// 获取数据成功后发出
633679
this.$emit('upload', result)
634680
return result
@@ -850,7 +896,7 @@ export default {
850896
}
851897
}
852898
} else {
853-
const empty = max - itemList.length + 1
899+
const empty = max - itemList.length
854900
if (max && l > empty) {
855901
l = empty
856902
}
@@ -945,7 +991,7 @@ export default {
945991
image.src = localSrc
946992
image.onload = () => {
947993
/**
948-
* @type LocalFileInfo
994+
* @type {LocalFileInfo}
949995
*/
950996
const localFileInfo = {
951997
localSrc,
@@ -958,7 +1004,6 @@ export default {
9581004
lastModified: file.lastModified,
9591005
isAnimated,
9601006
}
961-
console.log(localFileInfo)
9621007
resolve(localFileInfo)
9631008
image = null
9641009
}

src/plugins/custom/views/Demo.vue

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
<el-button @click="getValue('uploadEle4')">获取当前图像数据</el-button>
2020
</div>
2121
</el-form-item>
22+
<el-form-item label="动图检测示例">
23+
<upload-imgs ref="uploadEle32" :rules="rules" :multiple="true" :animated-check="true" />
24+
<div>
25+
<el-button @click="getValue('uploadEle32')">获取当前图像数据</el-button>
26+
</div>
27+
</el-form-item>
2228
<el-form-item label="禁用+初始化">
2329
<upload-imgs
2430
ref="uploadEle5"
@@ -132,6 +138,12 @@
132138
:fit="fit"
133139
:value="initData" />
134140
</el-form-item>
141+
<el-form-item label="自定义校验函数">
142+
<upload-imgs ref="uploadEle33" :rules="rules" :before-upload="beforeFuc" :multiple="true" />
143+
<div>
144+
<el-button @click="getValue('uploadEle33')">获取当前图像数据</el-button>
145+
</div>
146+
</el-form-item>
135147
</el-form>
136148
</div>
137149
</div>
@@ -214,6 +226,10 @@ export default {
214226
// // next()
215227
// },
216228
methods: {
229+
async beforeFuc() {
230+
this.$message.error('进入自定义校验函数, 并返回false终止上传')
231+
return false
232+
},
217233
async getValue(name) {
218234
console.log(await this.$refs[name].getValue())
219235
// eslint-disable-next-line

0 commit comments

Comments
 (0)