Skip to content

Commit

Permalink
fix(comp:upload): controlled update should trigger upload and abort (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sallerli1 committed Oct 23, 2023
1 parent 47b21e0 commit c068cd4
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 27 deletions.
14 changes: 14 additions & 0 deletions packages/components/upload/demo/Controlled.md
@@ -0,0 +1,14 @@
---
title:
zh: 受控使用
en: Controlled usage
order: 0
---

## zh

`files` 支持受控,添加文件到 `files` 中可自动上传文件,删除则可以自动终止上传。

## en

`files` supports controlled usage, file is auto uploaded after added to `files`, and aborts after removed.
45 changes: 45 additions & 0 deletions packages/components/upload/demo/Controlled.vue
@@ -0,0 +1,45 @@
<template>
<IxUpload v-model:files="files" action="https://run.mocky.io/v3/7564bc4f-780e-43f7-bc58-467959ae3354">
<IxButton>Upload</IxButton>
<template #list>
<IxUploadFiles type="text" />
</template>
</IxUpload>
<IxButton @click="addFile">addFile</IxButton>
<IxButton @click="clearFiles">clearFiles</IxButton>
</template>

<script setup lang="ts">
import type { UploadFile } from '@idux/components/upload'
import { ref } from 'vue'
const files = ref<UploadFile[]>([])
let keySeed = 0
const addFile = () => {
const newFile = new File(
[
new Blob([
Array.from(new Array(100))
.map(() => 'file content')
.join('\n'),
]),
],
'new_File',
{
type: 'text/plain',
},
)
files.value.push({
key: `newFile-${keySeed++}`,
raw: newFile,
name: newFile.name,
status: 'selected',
})
}
const clearFiles = () => {
files.value = []
}
</script>
5 changes: 3 additions & 2 deletions packages/components/upload/src/composables/useFilesData.ts
Expand Up @@ -6,7 +6,8 @@
*/

import type { UploadFile, UploadProps } from '../types'
import type { ComputedRef } from 'vue'

import { type ComputedRef, toRaw } from 'vue'

import { callEmit, useControlledProp } from '@idux/cdk/utils'

Expand Down Expand Up @@ -47,7 +48,7 @@ export function useFilesData(props: UploadProps): FilesDataContext {
}
})

setFileList(newFileList)
setFileList(toRaw(newFileList))

statusChangeFiles.forEach(file => {
callEmit(props.onFileStatusChange, file)
Expand Down
20 changes: 10 additions & 10 deletions packages/components/upload/src/composables/useRequest.ts
Expand Up @@ -46,20 +46,20 @@ export function useRequest(props: UploadProps, filesDataContext: FilesDataContex
}

function abort(file: UploadFile): void {
const curFile = getTargetFile(file, fileList.value)
if (!curFile) {
return
}
const curAbort = aborts.get(curFile.key)
curAbort?.()
updateFileStatus(curFile, 'abort')
fileUploading.value.splice(getTargetFileIndex(curFile, fileUploading.value), 1)
aborts.delete(curFile.key)
aborts.get(file.key)?.()

props.onRequestChange &&
callEmit(props.onRequestChange, {
status: 'abort',
file: { ...curFile },
file: { ...file },
})
fileUploading.value.splice(getTargetFileIndex(file, fileUploading.value), 1)
aborts.delete(file.key)

const curFile = getTargetFile(file, fileList.value)
if (curFile) {
updateFileStatus(curFile, 'abort')
}
}

async function startUpload(file: UploadFile): Promise<void> {
Expand Down
50 changes: 36 additions & 14 deletions packages/components/upload/src/composables/useUploadControl.ts
Expand Up @@ -10,26 +10,48 @@ import type { UploadFile } from '../types'

import { type ComputedRef, watch } from 'vue'

import { useState } from '@idux/cdk/utils'

import { getTargetFile } from '../utils/files'

export function useUploadControl(fileList: ComputedRef<UploadFile[]>, uploadRequest: UploadRequest): void {
const { startUpload, abort } = uploadRequest

watch(fileList, (currentFileList, preFileList) => {
currentFileList.forEach(file => {
const preFile = getTargetFile(file, preFileList)

if (!preFile && file.status === 'selected') {
startUpload(file)
const [proxyedFileList, setProxyedFileList] = useState<UploadFile[]>([...fileList.value])

watch(
fileList,
_fileList => {
setProxyedFileList([..._fileList])
},
{
deep: true,
},
)

watch(
[proxyedFileList, () => proxyedFileList.value.length],
([currentFileList, currentLength], [preFileList, preLength]) => {
if (currentLength === preLength) {
return
}
})

preFileList.forEach(file => {
const currentFile = getTargetFile(file, currentFileList)
currentFileList.forEach(file => {
const preFile = getTargetFile(file, preFileList)
console.log(preFile, file, currentFileList === preFileList)

if (!currentFile && file.status === 'uploading') {
abort(file)
}
})
})
if (!preFile && file.status === 'selected') {
startUpload(file)
}
})

preFileList.forEach(file => {
const currentFile = getTargetFile(file, currentFileList)

if (!currentFile && file.status === 'uploading') {
abort(file)
}
})
},
)
}
2 changes: 1 addition & 1 deletion packages/components/upload/src/types.ts
Expand Up @@ -71,7 +71,7 @@ export interface UploadRequestChangeOption<K = VKey> {
export const uploadProps = {
files: {
type: Array as PropType<UploadFile[]>,
default: [],
default: () => [],
},
accept: String,
action: {
Expand Down

0 comments on commit c068cd4

Please sign in to comment.