feat(upload): add keep-file-after-finish prop (#4085)

* on-finish 中保留 file对象
关闭 #3868

* 增加 keep-file-after-finish 属性允许用户配置在on-finish 中保留 file

关闭 #3868

Co-authored-by: Adang <lundang.liu@feima-inc.com>
This commit is contained in:
Adang 2022-12-18 13:19:03 +08:00 committed by GitHub
parent 415cf4a7db
commit dd953f2843
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 11 deletions

View File

@ -60,6 +60,7 @@ debug.vue
| show-trigger | `boolean` | `true` | 是否显示触发元素 | 2.21.5 |
| trigger-style | `Object \| string` | `undefined` | 触发器区域的样式 | 2.29.1 |
| with-credentials | `boolean` | `false` | 是否携带 Cookie | |
| keep-file-after-finish | `boolean` | `false` | 文件上传结束的回调中保留 File不被置为 null | |
| on-change | `(options: { file: UploadFileInfo, fileList: Array<UploadFileInfo>, event?: Event }) => void` | `() => {}` | 组件状态变化的回调,组件的任何文件状态变化都会触发回调 | |
| on-error | `(options: { file: UploadFileInfo, event?: ProgressEvent }) => UploadFileInfo \| void` | `undefined` | 文件上传失败的回调 | 2.24.0 |
| on-finish | `(options: { file: UploadFileInfo, event?: ProgressEvent }) => UploadFileInfo \| undefined` | `({ file }) => file` | 文件上传结束的回调,可以修改传入的 UploadFileInfo 或者返回一个新的 UploadFileInfo。注意file 将会下一次事件循环中被置为 null | |

View File

@ -1,12 +1,14 @@
<markdown>
# 上传完成的回调
你可以在回调中修改文件的属性
你可以在回调中修改文件的属性使用`keep-file-after-finish`允许在回调中返回File
</markdown>
<template>
KeepFileAfterFinish <n-switch v-model:value="keepFileAfterFinish" /><br>
<n-upload
action="__HTTP__://www.mocky.io/v2/5e4bafc63100007100d8b70f"
:keep-file-after-finish="keepFileAfterFinish"
@finish="handleFinish"
>
<n-button>上传文件</n-button>
@ -14,7 +16,7 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { defineComponent, ref } from 'vue'
import { useMessage } from 'naive-ui'
import type { UploadFileInfo } from 'naive-ui'
@ -29,6 +31,7 @@ export default defineComponent({
event?: ProgressEvent
}) => {
console.log(event)
console.log(file.file)
message.success((event?.target as XMLHttpRequest).response)
const ext = file.name.split('.')[1]
file.name = `更名.${ext}`
@ -36,6 +39,7 @@ export default defineComponent({
return file
}
return {
keepFileAfterFinish: ref(false),
message,
handleFinish
}

View File

@ -62,7 +62,8 @@ import style from './styles/index.cssr'
function createXhrHandlers (
inst: UploadInternalInst,
file: SettledFileInfo,
xhr: XMLHttpRequest
xhr: XMLHttpRequest,
keepFileAfterFinish?: boolean
): XhrHandlers {
const { doChange, xhrMap } = inst
let percentage = 0
@ -93,7 +94,7 @@ function createXhrHandlers (
let fileAfterChange: SettledFileInfo = Object.assign({}, file, {
status: 'finished',
percentage,
file: null
file: keepFileAfterFinish ? file : null
})
xhrMap.delete(file.id)
fileAfterChange = createSettledFileInfo(
@ -135,11 +136,20 @@ function customSubmitImpl (options: {
headers?: FuncOrRecordOrUndef
action?: string
withCredentials?: boolean
keepFileAfterFinish?: boolean
file: SettledFileInfo
customRequest: CustomRequest
}): void {
const { inst, file, data, headers, withCredentials, action, customRequest } =
options
const {
inst,
file,
data,
headers,
withCredentials,
action,
customRequest,
keepFileAfterFinish
} = options
const { doChange } = options.inst
let percentage = 0
customRequest({
@ -161,7 +171,7 @@ function customSubmitImpl (options: {
let fileAfterChange: SettledFileInfo = Object.assign({}, file, {
status: 'finished',
percentage,
file: null
file: keepFileAfterFinish ? file : null
})
fileAfterChange = createSettledFileInfo(
inst.onFinish?.({ file: fileAfterChange }) || fileAfterChange
@ -184,9 +194,10 @@ function customSubmitImpl (options: {
function registerHandler (
inst: UploadInternalInst,
file: SettledFileInfo,
request: XMLHttpRequest
request: XMLHttpRequest,
keepFileAfterFinish?: boolean
): void {
const handlers = createXhrHandlers(inst, file, request)
const handlers = createXhrHandlers(inst, file, request, keepFileAfterFinish)
request.onabort = handlers.handleXHRAbort
request.onerror = handlers.handleXHRError
request.onload = handlers.handleXHRLoad
@ -238,6 +249,7 @@ function submitImpl (
method,
action,
withCredentials,
keepFileAfterFinish,
responseType,
headers,
data
@ -245,6 +257,7 @@ function submitImpl (
method: string
action?: string
withCredentials: boolean
keepFileAfterFinish: boolean
responseType: XMLHttpRequestResponseType
headers: FuncOrRecordOrUndef
data: FuncOrRecordOrUndef
@ -257,7 +270,7 @@ function submitImpl (
const formData = new FormData()
appendData(formData, data, file)
formData.append(fieldName, file.file as File)
registerHandler(inst, file, request)
registerHandler(inst, file, request, keepFileAfterFinish)
if (action !== undefined) {
request.open(method.toUpperCase(), action)
setHeaders(request, headers, file)
@ -361,7 +374,8 @@ export const uploadProps = {
imageGroupProps: Object as PropType<ImageGroupProps>,
inputProps: Object as PropType<InputHTMLAttributes>,
triggerStyle: [String, Object] as PropType<CSSProperties | string>,
renderIcon: Object as PropType<RenderIcon>
renderIcon: Object as PropType<RenderIcon>,
keepFileAfterFinish: Boolean
} as const
export type UploadProps = ExtractPublicPropTypes<typeof uploadProps>
@ -510,6 +524,7 @@ export default defineComponent({
method,
action,
withCredentials,
keepFileAfterFinish,
headers,
data,
name: fieldName
@ -533,6 +548,7 @@ export default defineComponent({
file,
action,
withCredentials,
keepFileAfterFinish,
headers,
data,
customRequest: props.customRequest
@ -552,6 +568,7 @@ export default defineComponent({
method,
action,
withCredentials,
keepFileAfterFinish,
responseType: props.responseType,
headers,
data