feat(upload): add on-update:file-list prop (#243)

* feat(upload): add v-model:file-list

* doc(changelog)

* fix(upload): change the timing of doUpdateFileList call

Co-authored-by: wanli.song@tusimple.ai <wanli.song@tusimple.ai>
Co-authored-by: 07akioni <07akioni2@gmail.com>
This commit is contained in:
Wanli Song 2021-06-23 14:50:19 +08:00 committed by GitHub
parent 44946ecc9a
commit fc955ff9d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 37 additions and 14 deletions

View File

@ -11,6 +11,7 @@
- Add `n-carousel` component.
- Add `useThemeVars` composable to provide theme variables.
- `n-upload` add `on-update:file-list` prop, closes [#135](https://github.com/TuSimple/naive-ui/issues/135).
- `n-date-picker` add `update-value-on-close` prop.
### Fixes

View File

@ -11,6 +11,7 @@
- 新增 `n-carousel` 组件
- 新增 `useThemeVars` 函数提供主题变量
- `n-upload` 新增 `on-update:file-list` 属性,关闭 [#135](https://github.com/TuSimple/naive-ui/issues/135)
- `n-date-picker` 新增 `update-value-on-close` 属性
### Fixes

View File

@ -5,7 +5,8 @@ Example is only a joke.
```html
<n-upload
action="http://www.mocky.io/v2/5e4bafc63100007100d8b70f"
:file-list="fileList"
v-model:file-list="fileList"
@update:file-list="handleFileListChange"
@change="handleUploadChange"
@remove="handleRemove"
>
@ -68,6 +69,9 @@ export default defineComponent({
}, 4000)
})
}
},
handleFileListChange (value) {
message.info("Yes, file-list changed.")
}
}
}

View File

@ -36,6 +36,7 @@ default-files
| show-retry-button | `boolean` | `true` | Whether to show retry button (at file error status). |
| with-credentials | `boolean` | `false` | If cookie attached. |
| on-change | `(options: { file: UploadFile, fileList: Array<UploadFile>, event?: Event }) => void` | `() => {}` | The callback of status change of the component. Any file status change would fire the callback. |
| on-update:file-list | `(fileList: UploadFile[]) => void` | `undefined` | Callback function triggered on fileList changes. |
| on-finish | `(options: { file: UploadFile }) => UploadFile \| void` | `({ file }) => file` | The callback of file upload finish. You can modify the UploadFile or retun a new UploadFile. |
| on-remove | `(options: { file: UploadFile, fileList: Array<UploadFile> }) => boolean \| Promise<boolean> \| any` | `() => true` | The callback of file removal. Return false, promise resolve false or promise reject will cancel this removal. |
@ -49,14 +50,6 @@ default-files
| percentage | `number` | The progress percentage of file upload. It works when file is uploading. Not required in controlled manner. |
| file | `File` | The File object of the file in brower. Not required in controlled manner. |
## Events
### Upload Events
| Name | Parameters | Description |
| ------ | ------------------------------------------------- | ----------- |
| change | `(file: UploadFile, fileList: Array<UploadFile>)` | |
## Methods
### Upload Methods

View File

@ -5,9 +5,10 @@
```html
<n-upload
action="http://www.mocky.io/v2/5e4bafc63100007100d8b70f"
:file-list="fileList"
v-model:file-list="fileList"
@change="handleUploadChange"
@remove="handleRemove"
@update:file-list="handleFileListChange"
>
<n-button>上传文件</n-button>
</n-upload>
@ -65,6 +66,9 @@ export default defineComponent({
}, 4000)
})
}
},
handleFileListChange (value) {
message.info("是的file-list 的值变了")
}
}
}

View File

@ -37,6 +37,7 @@ default-files
| with-credentials | `boolean` | `false` | 是否携带 Cookie |
| on-change | `(options: { file: UploadFile, fileList: Array<UploadFile>, event?: Event }) => void` | `() => {}` | 组件状态变化的回调,组件的任何文件状态变化都会触发回调 |
| on-finish | `(options: { file: UploadFile }) => UploadFile \| void` | `({ file }) => file` | 文件上传结束的回调,可以修改传入的 UploadFile 或者返回一个新的 UploadFile |
| on-update:file-list | `(fileList: UploadFile[]) => void` | `undefined` | 当 file-list 改变时触发的回调函数 |
| on-remove | `(options: { file: UploadFile, fileList: Array<UploadFile> }) => boolean \| Promise<boolean> \| any` | `() => true` | 文件移除的回调,返回 false 或者 promise resolve false 或者 promise reject 会不执行这次删除 |
### UploadFile Type

View File

@ -11,7 +11,7 @@ import {
import { createId } from 'seemly'
import { useConfig, useTheme } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import { ExtractPublicPropTypes, getFirstSlotVNode, warn } from '../../_utils'
import { ExtractPublicPropTypes, getFirstSlotVNode, warn, MaybeArray, call } from '../../_utils'
import { NFadeInExpandTransition } from '../../_internal'
import { uploadLight, UploadTheme } from '../styles'
import NUploadFile from './UploadFile'
@ -26,7 +26,8 @@ import {
OnRemove,
OnDownload,
OnChange,
uploadInjectionKey
uploadInjectionKey,
OnUpdateFileList
} from './interface'
import { useMergedState } from 'vooks'
import { uploadDraggerKey } from './UploadDragger'
@ -209,6 +210,12 @@ const uploadProps = {
default: true
},
fileList: Array as PropType<FileInfo[]>,
'onUpdate:fileList': [Function, Array] as PropType<
MaybeArray<OnUpdateFileList>
>,
onUpdateFileList: [Function, Array] as PropType<
MaybeArray<OnUpdateFileList>
>,
fileListStyle: [String, Object] as PropType<string | CSSProperties>,
defaultFileList: {
type: Array as PropType<FileInfo[]>,
@ -248,6 +255,7 @@ export default defineComponent({
mergedClsPrefixRef
)
const uncontrolledFileListRef = ref(props.defaultFileList)
const controlledFileListRef = toRef(props, 'fileList')
const inputElRef = ref<HTMLInputElement | null>(null)
const draggerInsideRef = {
value: false
@ -255,7 +263,7 @@ export default defineComponent({
const dragOverRef = ref(false)
const XhrMap = new Map<string, XMLHttpRequest>()
const mergedFileListRef = useMergedState(
toRef(props, 'fileList'),
controlledFileListRef,
uncontrolledFileListRef
)
function openFileDialog (): void {
@ -293,6 +301,15 @@ export default defineComponent({
// May have bug! set to null?
target.value = ''
}
function doUpdateFileList (files: FileInfo[]): void {
const {
'onUpdate:fileList': _onUpdateFileList,
onUpdateFileList,
} = props
if (_onUpdateFileList) call(_onUpdateFileList, files)
if (onUpdateFileList) call(onUpdateFileList, files)
uncontrolledFileListRef.value = files
}
function handleFileAddition (files: FileList | null, e?: Event): void {
if (!files) return
Array.from(files).forEach((file) => {
@ -378,7 +395,7 @@ export default defineComponent({
event
})
}
uncontrolledFileListRef.value = fileListAfterChange
doUpdateFileList(fileListAfterChange)
} else if (__DEV__) {
warn('upload', 'File has no corresponding id in current file list.')
}

View File

@ -43,6 +43,8 @@ export type DoChange = (
}
) => void
export type OnUpdateFileList = (fileList: FileInfo[]) => void
export interface UploadInjection {
mergedClsPrefixRef: Ref<string>
mergedThemeRef: Ref<MergedTheme<UploadTheme>>