feat: add download transformFile previewFile actio
parent
3e8e90da5e
commit
548595959d
|
@ -1,5 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
dev: {
|
dev: {
|
||||||
componentName: 'select', // dev components
|
componentName: 'upload', // dev components
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import uniqBy from 'lodash/uniqBy';
|
import uniqBy from 'lodash/uniqBy';
|
||||||
import findIndex from 'lodash/findIndex';
|
import findIndex from 'lodash/findIndex';
|
||||||
|
import pick from 'lodash/pick';
|
||||||
import VcUpload from '../vc-upload';
|
import VcUpload from '../vc-upload';
|
||||||
import BaseMixin from '../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
import { getOptionProps, initDefaultProps, hasProp, getListeners } from '../_util/props-util';
|
import { getOptionProps, initDefaultProps, hasProp, getListeners } from '../_util/props-util';
|
||||||
|
@ -66,25 +67,12 @@ export default {
|
||||||
fileList: nextFileList,
|
fileList: nextFileList,
|
||||||
});
|
});
|
||||||
// fix ie progress
|
// fix ie progress
|
||||||
if (!window.FormData) {
|
if (!window.File || process.env.TEST_IE) {
|
||||||
this.autoUpdateProgress(0, targetItem);
|
this.autoUpdateProgress(0, targetItem);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
autoUpdateProgress(_, file) {
|
|
||||||
const getPercent = genPercentAdd();
|
onSuccess(response, file, xhr) {
|
||||||
let curPercent = 0;
|
|
||||||
this.clearProgressTimer();
|
|
||||||
this.progressTimer = setInterval(() => {
|
|
||||||
curPercent = getPercent(curPercent);
|
|
||||||
this.onProgress(
|
|
||||||
{
|
|
||||||
percent: curPercent * 100,
|
|
||||||
},
|
|
||||||
file,
|
|
||||||
);
|
|
||||||
}, 200);
|
|
||||||
},
|
|
||||||
onSuccess(response, file) {
|
|
||||||
this.clearProgressTimer();
|
this.clearProgressTimer();
|
||||||
try {
|
try {
|
||||||
if (typeof response === 'string') {
|
if (typeof response === 'string') {
|
||||||
|
@ -101,6 +89,7 @@ export default {
|
||||||
}
|
}
|
||||||
targetItem.status = 'done';
|
targetItem.status = 'done';
|
||||||
targetItem.response = response;
|
targetItem.response = response;
|
||||||
|
targetItem.xhr = xhr;
|
||||||
this.onChange({
|
this.onChange({
|
||||||
file: { ...targetItem },
|
file: { ...targetItem },
|
||||||
fileList,
|
fileList,
|
||||||
|
@ -140,19 +129,24 @@ export default {
|
||||||
this.$emit('reject', fileList);
|
this.$emit('reject', fileList);
|
||||||
},
|
},
|
||||||
handleRemove(file) {
|
handleRemove(file) {
|
||||||
const { remove } = this;
|
const { remove: onRemove } = this;
|
||||||
const { status } = file;
|
const { sFileList: fileList } = this.$data;
|
||||||
file.status = 'removed'; // eslint-disable-line
|
|
||||||
|
|
||||||
Promise.resolve(typeof remove === 'function' ? remove(file) : remove).then(ret => {
|
Promise.resolve(typeof onRemove === 'function' ? onRemove(file) : onRemove).then(ret => {
|
||||||
// Prevent removing file
|
// Prevent removing file
|
||||||
if (ret === false) {
|
if (ret === false) {
|
||||||
file.status = status;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const removedFileList = removeFileItem(file, this.sFileList);
|
const removedFileList = removeFileItem(file, fileList);
|
||||||
|
|
||||||
if (removedFileList) {
|
if (removedFileList) {
|
||||||
|
file.status = 'removed'; // eslint-disable-line
|
||||||
|
|
||||||
|
if (this.upload) {
|
||||||
|
this.upload.abort(file);
|
||||||
|
}
|
||||||
|
|
||||||
this.onChange({
|
this.onChange({
|
||||||
file,
|
file,
|
||||||
fileList: removedFileList,
|
fileList: removedFileList,
|
||||||
|
@ -178,14 +172,16 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
reBeforeUpload(file, fileList) {
|
reBeforeUpload(file, fileList) {
|
||||||
if (!this.beforeUpload) {
|
const { beforeUpload } = this.$props;
|
||||||
|
const { sFileList: stateFileList } = this.$data;
|
||||||
|
if (!beforeUpload) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const result = this.beforeUpload(file, fileList);
|
const result = beforeUpload(file, fileList);
|
||||||
if (result === false) {
|
if (result === false) {
|
||||||
this.onChange({
|
this.onChange({
|
||||||
file,
|
file,
|
||||||
fileList: uniqBy(this.sFileList.concat(fileList.map(fileToObject)), item => item.uid),
|
fileList: uniqBy(stateFileList.concat(fileList.map(fileToObject)), item => item.uid),
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -197,25 +193,45 @@ export default {
|
||||||
clearProgressTimer() {
|
clearProgressTimer() {
|
||||||
clearInterval(this.progressTimer);
|
clearInterval(this.progressTimer);
|
||||||
},
|
},
|
||||||
|
autoUpdateProgress(_, file) {
|
||||||
|
const getPercent = genPercentAdd();
|
||||||
|
let curPercent = 0;
|
||||||
|
this.clearProgressTimer();
|
||||||
|
this.progressTimer = setInterval(() => {
|
||||||
|
curPercent = getPercent(curPercent);
|
||||||
|
this.onProgress(
|
||||||
|
{
|
||||||
|
percent: curPercent * 100,
|
||||||
|
},
|
||||||
|
file,
|
||||||
|
);
|
||||||
|
}, 200);
|
||||||
|
},
|
||||||
renderUploadList(locale) {
|
renderUploadList(locale) {
|
||||||
const { showUploadList = {}, listType } = getOptionProps(this);
|
const {
|
||||||
const { showRemoveIcon, showPreviewIcon } = showUploadList;
|
showUploadList = {},
|
||||||
|
listType,
|
||||||
|
previewFile,
|
||||||
|
disabled,
|
||||||
|
locale: propLocale,
|
||||||
|
} = getOptionProps(this);
|
||||||
|
const { showRemoveIcon, showPreviewIcon, showDownloadIcon } = showUploadList;
|
||||||
|
const { sFileList: fileList } = this.$data;
|
||||||
const uploadListProps = {
|
const uploadListProps = {
|
||||||
props: {
|
props: {
|
||||||
listType,
|
listType,
|
||||||
items: this.sFileList,
|
items: fileList,
|
||||||
showRemoveIcon,
|
previewFile,
|
||||||
|
showRemoveIcon: !disabled && showRemoveIcon,
|
||||||
showPreviewIcon,
|
showPreviewIcon,
|
||||||
locale: { ...locale, ...this.$props.locale },
|
showDownloadIcon,
|
||||||
|
locale: { ...locale, ...propLocale },
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
remove: this.handleManualRemove,
|
remove: this.handleManualRemove,
|
||||||
|
...pick(getListeners(this), ['download', 'preview']), // 如果没有配置该事件,不要传递, uploadlist 会有相应逻辑
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const listeners = getListeners(this);
|
|
||||||
if (listeners.preview) {
|
|
||||||
uploadListProps.on.preview = listeners.preview;
|
|
||||||
}
|
|
||||||
return <UploadList {...uploadListProps} />;
|
return <UploadList {...uploadListProps} />;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -227,7 +243,7 @@ export default {
|
||||||
type,
|
type,
|
||||||
disabled,
|
disabled,
|
||||||
} = getOptionProps(this);
|
} = getOptionProps(this);
|
||||||
|
const { sFileList: fileList, dragState } = this.$data;
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||||
const prefixCls = getPrefixCls('upload', customizePrefixCls);
|
const prefixCls = getPrefixCls('upload', customizePrefixCls);
|
||||||
|
|
||||||
|
@ -261,8 +277,8 @@ export default {
|
||||||
if (type === 'drag') {
|
if (type === 'drag') {
|
||||||
const dragCls = classNames(prefixCls, {
|
const dragCls = classNames(prefixCls, {
|
||||||
[`${prefixCls}-drag`]: true,
|
[`${prefixCls}-drag`]: true,
|
||||||
[`${prefixCls}-drag-uploading`]: this.sFileList.some(file => file.status === 'uploading'),
|
[`${prefixCls}-drag-uploading`]: fileList.some(file => file.status === 'uploading'),
|
||||||
[`${prefixCls}-drag-hover`]: this.dragState === 'dragover',
|
[`${prefixCls}-drag-hover`]: dragState === 'dragover',
|
||||||
[`${prefixCls}-disabled`]: disabled,
|
[`${prefixCls}-disabled`]: disabled,
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
|
@ -290,7 +306,7 @@ export default {
|
||||||
|
|
||||||
// Remove id to avoid open by label when trigger is hidden
|
// Remove id to avoid open by label when trigger is hidden
|
||||||
// https://github.com/ant-design/ant-design/issues/14298
|
// https://github.com/ant-design/ant-design/issues/14298
|
||||||
if (!children) {
|
if (!children || disabled) {
|
||||||
delete vcUploadProps.props.id;
|
delete vcUploadProps.props.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +318,7 @@ export default {
|
||||||
|
|
||||||
if (listType === 'picture-card') {
|
if (listType === 'picture-card') {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span class={`${prefixCls}-picture-card-wrapper`}>
|
||||||
{uploadList}
|
{uploadList}
|
||||||
{uploadButton}
|
{uploadButton}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -2,51 +2,13 @@ import BaseMixin from '../_util/BaseMixin';
|
||||||
import { getOptionProps, initDefaultProps, getListeners } from '../_util/props-util';
|
import { getOptionProps, initDefaultProps, getListeners } from '../_util/props-util';
|
||||||
import getTransitionProps from '../_util/getTransitionProps';
|
import getTransitionProps from '../_util/getTransitionProps';
|
||||||
import { ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumerProps } from '../config-provider';
|
||||||
|
import { previewImage, isImageUrl } from './utils';
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
import Tooltip from '../tooltip';
|
import Tooltip from '../tooltip';
|
||||||
import Progress from '../progress';
|
import Progress from '../progress';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { UploadListProps } from './interface';
|
import { UploadListProps } from './interface';
|
||||||
|
|
||||||
const imageTypes = ['image', 'webp', 'png', 'svg', 'gif', 'jpg', 'jpeg', 'bmp', 'dpg', 'ico'];
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
|
|
||||||
const previewFile = (file, callback) => {
|
|
||||||
if (file.type && !imageTypes.includes(file.type)) {
|
|
||||||
callback('');
|
|
||||||
}
|
|
||||||
const reader = new window.FileReader();
|
|
||||||
reader.onloadend = () => callback(reader.result);
|
|
||||||
reader.readAsDataURL(file);
|
|
||||||
};
|
|
||||||
|
|
||||||
const extname = url => {
|
|
||||||
if (!url) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
const temp = url.split('/');
|
|
||||||
const filename = temp[temp.length - 1];
|
|
||||||
const filenameWithoutSuffix = filename.split(/#|\?/)[0];
|
|
||||||
return (/\.[^./\\]*$/.exec(filenameWithoutSuffix) || [''])[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
const isImageUrl = file => {
|
|
||||||
if (imageTypes.includes(file.type)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const url = file.thumbUrl || file.url;
|
|
||||||
const extension = extname(url);
|
|
||||||
if (/^data:image\//.test(url) || /(webp|svg|png|gif|jpg|jpeg|bmp|dpg|ico)$/i.test(extension)) {
|
|
||||||
return true;
|
|
||||||
} else if (/^data:/.test(url)) {
|
|
||||||
// other file types of base64
|
|
||||||
return false;
|
|
||||||
} else if (extension) {
|
|
||||||
// other file types which have extension
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AUploadList',
|
name: 'AUploadList',
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
|
@ -57,43 +19,43 @@ export default {
|
||||||
showInfo: false,
|
showInfo: false,
|
||||||
},
|
},
|
||||||
showRemoveIcon: true,
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: true,
|
||||||
showPreviewIcon: true,
|
showPreviewIcon: true,
|
||||||
|
previewFile: previewImage,
|
||||||
}),
|
}),
|
||||||
inject: {
|
inject: {
|
||||||
configProvider: { default: () => ConfigConsumerProps },
|
configProvider: { default: () => ConfigConsumerProps },
|
||||||
},
|
},
|
||||||
updated() {
|
updated() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.listType !== 'picture' && this.listType !== 'picture-card') {
|
const { listType, items, previewFile } = this.$props;
|
||||||
|
if (listType !== 'picture' && listType !== 'picture-card') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(this.items || []).forEach(file => {
|
(items || []).forEach(file => {
|
||||||
if (
|
if (
|
||||||
typeof document === 'undefined' ||
|
typeof document === 'undefined' ||
|
||||||
typeof window === 'undefined' ||
|
typeof window === 'undefined' ||
|
||||||
!window.FileReader ||
|
!window.FileReader ||
|
||||||
!window.File ||
|
!window.File ||
|
||||||
!(file.originFileObj instanceof window.File) ||
|
!(file.originFileObj instanceof File || file.originFileObj instanceof Blob) ||
|
||||||
file.thumbUrl !== undefined
|
file.thumbUrl !== undefined
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*eslint-disable */
|
/*eslint-disable */
|
||||||
file.thumbUrl = '';
|
file.thumbUrl = '';
|
||||||
/*eslint -enable */
|
if (previewFile) {
|
||||||
previewFile(file.originFileObj, previewDataUrl => {
|
previewFile(file.originFileObj).then(previewDataUrl => {
|
||||||
// Need append '' to avoid dead loop
|
// Need append '' to avoid dead loop
|
||||||
file.thumbUrl = previewDataUrl || '';
|
file.thumbUrl = previewDataUrl || '';
|
||||||
/*eslint -enable */
|
this.$forceUpdate();
|
||||||
this.$forceUpdate();
|
});
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClose(file) {
|
|
||||||
this.$emit('remove', file);
|
|
||||||
},
|
|
||||||
handlePreview(file, e) {
|
handlePreview(file, e) {
|
||||||
const { preview } = getListeners(this);
|
const { preview } = getListeners(this);
|
||||||
if (!preview) {
|
if (!preview) {
|
||||||
|
@ -102,6 +64,18 @@ export default {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return this.$emit('preview', file);
|
return this.$emit('preview', file);
|
||||||
},
|
},
|
||||||
|
handleDownload(file) {
|
||||||
|
const { download } = getListeners(this);
|
||||||
|
if (typeof download === 'function') {
|
||||||
|
download(file);
|
||||||
|
} else if (file.url) {
|
||||||
|
window.open(file.url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClose(file) {
|
||||||
|
this.$emit('remove', file);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
|
@ -110,7 +84,9 @@ export default {
|
||||||
listType,
|
listType,
|
||||||
showPreviewIcon,
|
showPreviewIcon,
|
||||||
showRemoveIcon,
|
showRemoveIcon,
|
||||||
|
showDownloadIcon,
|
||||||
locale,
|
locale,
|
||||||
|
progressAttr,
|
||||||
} = getOptionProps(this);
|
} = getOptionProps(this);
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||||
const prefixCls = getPrefixCls('upload', customizePrefixCls);
|
const prefixCls = getPrefixCls('upload', customizePrefixCls);
|
||||||
|
@ -126,7 +102,11 @@ export default {
|
||||||
icon = <Icon class={`${prefixCls}-list-item-thumbnail`} type="picture" theme="twoTone" />;
|
icon = <Icon class={`${prefixCls}-list-item-thumbnail`} type="picture" theme="twoTone" />;
|
||||||
} else {
|
} else {
|
||||||
const thumbnail = isImageUrl(file) ? (
|
const thumbnail = isImageUrl(file) ? (
|
||||||
<img src={file.thumbUrl || file.url} alt={file.name} />
|
<img
|
||||||
|
src={file.thumbUrl || file.url}
|
||||||
|
alt={file.name}
|
||||||
|
class={`${prefixCls}-list-item-image`}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Icon type="file" class={`${prefixCls}-list-item-icon`} theme="twoTone" />
|
<Icon type="file" class={`${prefixCls}-list-item-icon`} theme="twoTone" />
|
||||||
);
|
);
|
||||||
|
@ -147,7 +127,7 @@ export default {
|
||||||
if (file.status === 'uploading') {
|
if (file.status === 'uploading') {
|
||||||
const progressProps = {
|
const progressProps = {
|
||||||
props: {
|
props: {
|
||||||
...this.progressAttr,
|
...progressAttr,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
percent: file.percent,
|
percent: file.percent,
|
||||||
},
|
},
|
||||||
|
@ -164,30 +144,64 @@ export default {
|
||||||
const infoUploadingClass = classNames({
|
const infoUploadingClass = classNames({
|
||||||
[`${prefixCls}-list-item`]: true,
|
[`${prefixCls}-list-item`]: true,
|
||||||
[`${prefixCls}-list-item-${file.status}`]: true,
|
[`${prefixCls}-list-item-${file.status}`]: true,
|
||||||
|
[`${prefixCls}-list-item-list-type-${listType}`]: true,
|
||||||
});
|
});
|
||||||
const linkProps =
|
const linkProps =
|
||||||
typeof file.linkProps === 'string' ? JSON.parse(file.linkProps) : file.linkProps;
|
typeof file.linkProps === 'string' ? JSON.parse(file.linkProps) : file.linkProps;
|
||||||
const preview = file.url ? (
|
|
||||||
<a
|
const removeIcon = showRemoveIcon ? (
|
||||||
target="_blank"
|
<Icon type="delete" title={locale.removeFile} onClick={() => this.handleClose(file)} />
|
||||||
rel="noopener noreferrer"
|
) : null;
|
||||||
class={`${prefixCls}-list-item-name`}
|
const downloadIcon =
|
||||||
title={file.name}
|
showDownloadIcon && file.status === 'done' ? (
|
||||||
{...linkProps}
|
<Icon
|
||||||
href={file.url}
|
type="download"
|
||||||
onClick={e => this.handlePreview(file, e)}
|
title={locale.downloadFile}
|
||||||
>
|
onClick={() => this.handleDownload(file)}
|
||||||
{file.name}
|
/>
|
||||||
</a>
|
) : null;
|
||||||
) : (
|
const downloadOrDelete = listType !== 'picture-card' && (
|
||||||
<span
|
<span
|
||||||
class={`${prefixCls}-list-item-name`}
|
key="download-delete"
|
||||||
onClick={e => this.handlePreview(file, e)}
|
class={`${prefixCls}-list-item-card-actions ${listType === 'picture' ? 'picture' : ''}`}
|
||||||
title={file.name}
|
|
||||||
>
|
>
|
||||||
{file.name}
|
{downloadIcon && <a title={locale.downloadFile}>{downloadIcon}</a>}
|
||||||
|
{removeIcon && <a title={locale.removeFile}>{removeIcon}</a>}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
const listItemNameClass = classNames({
|
||||||
|
[`${prefixCls}-list-item-name`]: true,
|
||||||
|
[`${prefixCls}-list-item-name-icon-count-${
|
||||||
|
[downloadIcon, removeIcon].filter(x => x).length
|
||||||
|
}`]: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const preview = file.url
|
||||||
|
? [
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class={listItemNameClass}
|
||||||
|
title={file.name}
|
||||||
|
{...linkProps}
|
||||||
|
href={file.url}
|
||||||
|
onClick={e => this.handlePreview(file, e)}
|
||||||
|
>
|
||||||
|
{file.name}
|
||||||
|
</a>,
|
||||||
|
downloadOrDelete,
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
<span
|
||||||
|
key="view"
|
||||||
|
class={`${prefixCls}-list-item-name`}
|
||||||
|
onClick={e => this.handlePreview(file, e)}
|
||||||
|
title={file.name}
|
||||||
|
>
|
||||||
|
{file.name}
|
||||||
|
</span>,
|
||||||
|
downloadOrDelete,
|
||||||
|
];
|
||||||
const style =
|
const style =
|
||||||
file.url || file.thumbUrl
|
file.url || file.thumbUrl
|
||||||
? undefined
|
? undefined
|
||||||
|
@ -207,55 +221,41 @@ export default {
|
||||||
<Icon type="eye-o" />
|
<Icon type="eye-o" />
|
||||||
</a>
|
</a>
|
||||||
) : null;
|
) : null;
|
||||||
const iconProps = {
|
const actions = listType === 'picture-card' && file.status !== 'uploading' && (
|
||||||
props: {
|
<span class={`${prefixCls}-list-item-actions`}>
|
||||||
type: 'delete',
|
{previewIcon}
|
||||||
title: locale.removeFile,
|
{file.status === 'done' && downloadIcon}
|
||||||
},
|
{removeIcon}
|
||||||
on: {
|
</span>
|
||||||
click: () => {
|
);
|
||||||
this.handleClose(file);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const iconProps1 = { ...iconProps, ...{ props: { type: 'close' } } };
|
|
||||||
const removeIcon = showRemoveIcon ? <Icon {...iconProps} /> : null;
|
|
||||||
const removeIconClose = showRemoveIcon ? <Icon {...iconProps1} /> : null;
|
|
||||||
const actions =
|
|
||||||
listType === 'picture-card' && file.status !== 'uploading' ? (
|
|
||||||
<span class={`${prefixCls}-list-item-actions`}>
|
|
||||||
{previewIcon}
|
|
||||||
{removeIcon}
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
removeIconClose
|
|
||||||
);
|
|
||||||
let message;
|
let message;
|
||||||
if (file.response && typeof file.response === 'string') {
|
if (file.response && typeof file.response === 'string') {
|
||||||
message = file.response;
|
message = file.response;
|
||||||
} else {
|
} else {
|
||||||
message = (file.error && file.error.statusText) || locale.uploadError;
|
message = (file.error && file.error.statusText) || locale.uploadError;
|
||||||
}
|
}
|
||||||
const iconAndPreview =
|
const iconAndPreview = (
|
||||||
file.status === 'error' ? (
|
<span>
|
||||||
<Tooltip title={message}>
|
{icon}
|
||||||
{icon}
|
{preview}
|
||||||
{preview}
|
</span>
|
||||||
</Tooltip>
|
);
|
||||||
) : (
|
|
||||||
<span>
|
|
||||||
{icon}
|
|
||||||
{preview}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
const transitionProps = getTransitionProps('fade');
|
const transitionProps = getTransitionProps('fade');
|
||||||
return (
|
const dom = (
|
||||||
<div class={infoUploadingClass} key={file.uid}>
|
<div class={infoUploadingClass} key={file.uid}>
|
||||||
<div class={`${prefixCls}-list-item-info`}>{iconAndPreview}</div>
|
<div class={`${prefixCls}-list-item-info`}>{iconAndPreview}</div>
|
||||||
{actions}
|
{actions}
|
||||||
<transition {...transitionProps}>{progress}</transition>
|
<transition {...transitionProps}>{progress}</transition>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
const listContainerNameClass = classNames({
|
||||||
|
[`${prefixCls}-list-picture-card-container`]: listType === 'picture-card',
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<div key={file.uid} class={listContainerNameClass}>
|
||||||
|
{file.status === 'error' ? <Tooltip title={message}>{dom}</Tooltip> : <span>{dom}</span>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
const listClassNames = classNames({
|
const listClassNames = classNames({
|
||||||
[`${prefixCls}-list`]: true,
|
[`${prefixCls}-list`]: true,
|
||||||
|
|
|
@ -56,15 +56,15 @@ The return value of function `beforeUpload` can be a Promise to check asynchrono
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeUpload(file) {
|
beforeUpload(file) {
|
||||||
const isJPG = file.type === 'image/jpeg';
|
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
|
||||||
if (!isJPG) {
|
if (!isJpgOrPng) {
|
||||||
this.$message.error('You can only upload JPG file!');
|
this.$message.error('You can only upload JPG file!');
|
||||||
}
|
}
|
||||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||||
if (!isLt2M) {
|
if (!isLt2M) {
|
||||||
this.$message.error('Image must smaller than 2MB!');
|
this.$message.error('Image must smaller than 2MB!');
|
||||||
}
|
}
|
||||||
return isJPG && isLt2M;
|
return isJpgOrPng && isLt2M;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<cn>
|
||||||
|
#### 点击上传
|
||||||
|
经典款式,用户点击按钮弹出文件选择框。
|
||||||
|
</cn>
|
||||||
|
|
||||||
|
<us>
|
||||||
|
#### Upload by clicking
|
||||||
|
Classic mode. File selection dialog pops up when upload button is clicked.
|
||||||
|
</us>
|
||||||
|
|
||||||
|
```tpl
|
||||||
|
<template>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
:multiple="true"
|
||||||
|
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
|
||||||
|
:headers="headers"
|
||||||
|
@change="handleChange"
|
||||||
|
>
|
||||||
|
<a-button> <a-icon type="upload" /> Click to Upload </a-button>
|
||||||
|
</a-upload>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
headers: {
|
||||||
|
authorization: 'authorization-text',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleChange(info) {
|
||||||
|
if (info.file.status !== 'uploading') {
|
||||||
|
console.log(info.file, info.fileList);
|
||||||
|
}
|
||||||
|
if (info.file.status === 'done') {
|
||||||
|
this.$message.success(`${info.file.name} file uploaded successfully`);
|
||||||
|
} else if (info.file.status === 'error') {
|
||||||
|
this.$message.error(`${info.file.name} file upload failed.`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
|
@ -3,7 +3,6 @@
|
||||||
使用 `fileList` 对列表进行完全控制,可以实现各种自定义功能,以下演示三种情况:
|
使用 `fileList` 对列表进行完全控制,可以实现各种自定义功能,以下演示三种情况:
|
||||||
1) 上传列表数量的限制。
|
1) 上传列表数量的限制。
|
||||||
2) 读取远程路径并显示链接。
|
2) 读取远程路径并显示链接。
|
||||||
3) 按照服务器返回信息筛选成功上传的文件。
|
|
||||||
</cn>
|
</cn>
|
||||||
|
|
||||||
<us>
|
<us>
|
||||||
|
@ -11,7 +10,6 @@
|
||||||
You can gain full control over filelist by configuring `fileList`. You can accomplish all kinds of customed functions. The following shows three circumstances:
|
You can gain full control over filelist by configuring `fileList`. You can accomplish all kinds of customed functions. The following shows three circumstances:
|
||||||
1) limit the number of uploaded files.
|
1) limit the number of uploaded files.
|
||||||
2) read from response and show file link.
|
2) read from response and show file link.
|
||||||
3) filter successfully uploaded files according to response from server.
|
|
||||||
</us>
|
</us>
|
||||||
|
|
||||||
```tpl
|
```tpl
|
||||||
|
|
|
@ -8,6 +8,8 @@ import Drag from './drag.md';
|
||||||
import PictureStyle from './picture-style.md';
|
import PictureStyle from './picture-style.md';
|
||||||
import UploadManually from './upload-manually.md';
|
import UploadManually from './upload-manually.md';
|
||||||
import Directory from './directory.md';
|
import Directory from './directory.md';
|
||||||
|
import PreviewFile from './preview-file';
|
||||||
|
import TransformFile from './transform-file';
|
||||||
|
|
||||||
import CN from '../index.zh-CN.md';
|
import CN from '../index.zh-CN.md';
|
||||||
import US from '../index.en-US.md';
|
import US from '../index.en-US.md';
|
||||||
|
@ -52,6 +54,8 @@ export default {
|
||||||
<PictureStyle />
|
<PictureStyle />
|
||||||
<UploadManually />
|
<UploadManually />
|
||||||
<Directory />
|
<Directory />
|
||||||
|
<PreviewFile />
|
||||||
|
<TransformFile />
|
||||||
<api>
|
<api>
|
||||||
<template slot="cn">
|
<template slot="cn">
|
||||||
<CN />
|
<CN />
|
||||||
|
|
|
@ -18,7 +18,7 @@ After users upload picture, the thumbnail will be shown in list. The upload butt
|
||||||
@preview="handlePreview"
|
@preview="handlePreview"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
>
|
>
|
||||||
<div v-if="fileList.length < 3">
|
<div v-if="fileList.length < 8">
|
||||||
<a-icon type="plus" />
|
<a-icon type="plus" />
|
||||||
<div class="ant-upload-text">Upload</div>
|
<div class="ant-upload-text">Upload</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,6 +29,14 @@ After users upload picture, the thumbnail will be shown in list. The upload butt
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
function getBase64(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
reader.onload = () => resolve(reader.result);
|
||||||
|
reader.onerror = error => reject(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -37,10 +45,33 @@ After users upload picture, the thumbnail will be shown in list. The upload butt
|
||||||
fileList: [
|
fileList: [
|
||||||
{
|
{
|
||||||
uid: '-1',
|
uid: '-1',
|
||||||
name: 'xxx.png',
|
name: 'image.png',
|
||||||
status: 'done',
|
status: 'done',
|
||||||
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
uid: '-2',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uid: '-3',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uid: '-4',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uid: '-5',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'error',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -48,8 +79,11 @@ After users upload picture, the thumbnail will be shown in list. The upload butt
|
||||||
handleCancel() {
|
handleCancel() {
|
||||||
this.previewVisible = false;
|
this.previewVisible = false;
|
||||||
},
|
},
|
||||||
handlePreview(file) {
|
async handlePreview(file) {
|
||||||
this.previewImage = file.url || file.thumbUrl;
|
if (!file.url && !file.preview) {
|
||||||
|
file.preview = await getBase64(file.originFileObj);
|
||||||
|
}
|
||||||
|
this.previewImage = file.url || file.preview;
|
||||||
this.previewVisible = true;
|
this.previewVisible = true;
|
||||||
},
|
},
|
||||||
handleChange({ fileList }) {
|
handleChange({ fileList }) {
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<cn>
|
||||||
|
#### 自定义预览
|
||||||
|
自定义本地预览,用于处理非图片格式文件(例如视频文件)。
|
||||||
|
</cn>
|
||||||
|
|
||||||
|
<us>
|
||||||
|
#### Customize preview file
|
||||||
|
Customize local preview. Can handle with non-image format files such as video.
|
||||||
|
</us>
|
||||||
|
|
||||||
|
```tpl
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-upload
|
||||||
|
listType="picture"
|
||||||
|
action="//jsonplaceholder.typicode.com/posts/"
|
||||||
|
:previewFile="previewFile"
|
||||||
|
>
|
||||||
|
<a-button> <a-icon type="upload" /> Upload </a-button>
|
||||||
|
</a-upload>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
previewFile(file) {
|
||||||
|
console.log('Your upload file:', file);
|
||||||
|
// Your process logic. Here we just mock to the same file
|
||||||
|
return fetch('https://next.json-generator.com/api/json/get/4ytyBoLK8', {
|
||||||
|
method: 'POST',
|
||||||
|
body: file,
|
||||||
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(({ thumbnail }) => thumbnail);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
|
@ -0,0 +1,48 @@
|
||||||
|
<cn>
|
||||||
|
#### 上传前转换文件
|
||||||
|
使用 `transformFile` 转换上传的文件(例如添加水印)。
|
||||||
|
</cn>
|
||||||
|
|
||||||
|
<us>
|
||||||
|
#### Transform file before request
|
||||||
|
Use `transformFile` for transform file before request such as add a watermark.
|
||||||
|
</us>
|
||||||
|
|
||||||
|
```tpl
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-upload
|
||||||
|
listType="picture"
|
||||||
|
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
|
||||||
|
:transformFile="transformFile"
|
||||||
|
>
|
||||||
|
<a-button> <a-icon type="upload" /> Upload </a-button>
|
||||||
|
</a-upload>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
transformFile(file) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
reader.onload = () => {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = reader.result;
|
||||||
|
img.onload = () => {
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
ctx.fillStyle = 'red';
|
||||||
|
ctx.textBaseline = 'middle';
|
||||||
|
ctx.fillText('Ant Design', 20, 20);
|
||||||
|
canvas.toBlob(resolve);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
|
@ -1,33 +1,37 @@
|
||||||
## API
|
## API
|
||||||
|
|
||||||
| Property | Description | Type | Default |
|
| Property | Description | Type | Default | Version |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| accept | File types that can be accepted. See [input accept Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) | string | - |
|
| accept | File types that can be accepted. See [input accept Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) | string | - | |
|
||||||
| action | Uploading URL | string\|(file) => `Promise` | - |
|
| action | Uploading URL | string\|(file) => `Promise` | - | |
|
||||||
| directory | support upload whole directory ([caniuse](https://caniuse.com/#feat=input-file-directory)) | boolean | false |
|
| method | http method of upload request | string | 'post' | 1.5.0 |
|
||||||
| beforeUpload | Hook function which will be executed before uploading. Uploading will be stopped with `false` or a rejected Promise returned. **Warning:this function is not supported in IE9**。 | (file, fileList) => `boolean | Promise` | - |
|
| directory | support upload whole directory ([caniuse](https://caniuse.com/#feat=input-file-directory)) | boolean | false | |
|
||||||
| customRequest | override for the default xhr behavior allowing for additional customization and ability to implement your own XMLHttpRequest | Function | - |
|
| beforeUpload | Hook function which will be executed before uploading. Uploading will be stopped with `false` or a rejected Promise returned. **Warning:this function is not supported in IE9**。 | (file, fileList) => `boolean | Promise` | - | |
|
||||||
| data | Uploading params or function which can return uploading params. | object\|function(file) | - |
|
| customRequest | override for the default xhr behavior allowing for additional customization and ability to implement your own XMLHttpRequest | Function | - | |
|
||||||
| defaultFileList | Default list of files that have been uploaded. | object\[] | - |
|
| data | Uploading params or function which can return uploading params. | object\|function(file) | - | |
|
||||||
| disabled | disable upload button | boolean | false |
|
| defaultFileList | Default list of files that have been uploaded. | object\[] | - | |
|
||||||
| fileList | List of files that have been uploaded (controlled). Here is a common issue [#2423](https://github.com/ant-design/ant-design/issues/2423) when using it | object\[] | - |
|
| disabled | disable upload button | boolean | false | |
|
||||||
| headers | Set request headers, valid above IE10. | object | - |
|
| fileList | List of files that have been uploaded (controlled). Here is a common issue [#2423](https://github.com/ant-design/ant-design/issues/2423) when using it | object\[] | - | |
|
||||||
| listType | Built-in stylesheets, support for three types: `text`, `picture` or `picture-card` | string | 'text' |
|
| headers | Set request headers, valid above IE10. | object | - | |
|
||||||
| multiple | Whether to support selected multiple file. `IE10+` supported. You can select multiple files with CTRL holding down while multiple is set to be true | boolean | false |
|
| listType | Built-in stylesheets, support for three types: `text`, `picture` or `picture-card` | string | 'text' | |
|
||||||
| name | The name of uploading file | string | 'file' |
|
| multiple | Whether to support selected multiple file. `IE10+` supported. You can select multiple files with CTRL holding down while multiple is set to be true | boolean | false | |
|
||||||
| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon` and `showRemoveIcon` individually | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true |
|
| name | The name of uploading file | string | 'file' | |
|
||||||
| supportServerRender | Need to be turned on while the server side is rendering. | boolean | false |
|
| previewFile | Customize preview file logic | (file: File \| Blob) => Promise<dataURL: string> | - | 1.5.0 |
|
||||||
| withCredentials | ajax upload with cookie sent | boolean | false |
|
| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon` and `showRemoveIcon` individually | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | |
|
||||||
| openFileDialogOnClick | click open file dialog | boolean | true |
|
| supportServerRender | Need to be turned on while the server side is rendering. | boolean | false | |
|
||||||
| remove | A callback function, will be executed when removing file button is clicked, remove event will be prevented when return value is `false` or a Promise which resolve(false) or reject. | Function(file): `boolean | Promise` | - |
|
| withCredentials | ajax upload with cookie sent | boolean | false | |
|
||||||
|
| openFileDialogOnClick | click open file dialog | boolean | true | |
|
||||||
|
| remove | A callback function, will be executed when removing file button is clicked, remove event will be prevented when return value is `false` or a Promise which resolve(false) or reject. | Function(file): `boolean | Promise` | - | |
|
||||||
|
| transformFile | Customize transform file before request | Function(file): `string | Blob | File | Promise<string | Blob | File>` | - | 1.5.0 |
|
||||||
|
|
||||||
### events
|
### events
|
||||||
|
|
||||||
| Events Name | Description | Arguments |
|
| Events Name | Description | Arguments | Version |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| change | A callback function, can be executed when uploading state is changing. See [change](#change) | Function | - |
|
| change | A callback function, can be executed when uploading state is changing. See [change](#change) | Function | - | |
|
||||||
| preview | A callback function, will be executed when file link or preview icon is clicked. | Function(file) | - |
|
| preview | A callback function, will be executed when file link or preview icon is clicked. | Function(file) | - | |
|
||||||
| reject | A callback function, will be executed when drop files is not accept. | Function(fileList) | - |
|
| download | Click the method to download the file, pass the method to perform the method logic, do not pass the default jump to the new TAB. | Function(file): void | Jump to new TAB | 1.5.0 |
|
||||||
|
| reject | A callback function, will be executed when drop files is not accept. | Function(fileList) | - | |
|
||||||
|
|
||||||
### change
|
### change
|
||||||
|
|
||||||
|
@ -48,10 +52,11 @@ When uploading state change, it returns:
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
uid: 'uid', // unique identifier, negative is recommend, to prevent interference with internal generated id
|
uid: 'uid', // unique identifier, negative is recommend, to prevent interference with internal generated id
|
||||||
name: 'xx.png' // file name
|
name: 'xx.png', // file name
|
||||||
status: 'done', // options:uploading, done, error, removed
|
status: 'done', // options:uploading, done, error, removed
|
||||||
response: '{"status": "success"}', // response from server
|
response: '{"status": "success"}', // response from server
|
||||||
linkProps: '{"download": "image"}', // additional html props of file link
|
linkProps: '{"download": "image"}', // additional html props of file link
|
||||||
|
xhr: 'XMLHttpRequest{ ... }', // XMLHttpRequest Header
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,37 @@
|
||||||
## API
|
## API
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| accept | 接受上传的文件类型, 详见 [input accept Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) | string | 无 |
|
| accept | 接受上传的文件类型, 详见 [input accept Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) | string | 无 | |
|
||||||
| action | 上传的地址 | string\|(file) => `Promise` | 无 |
|
| action | 上传的地址 | string\|(file) => `Promise` | 无 | |
|
||||||
| directory | 支持上传文件夹([caniuse](https://caniuse.com/#feat=input-file-directory)) | boolean | false |
|
| method | 上传请求的 http method | string | 'post' | 1.5.0 |
|
||||||
| beforeUpload | 上传文件之前的钩子,参数为上传的文件,若返回 `false` 则停止上传。支持返回一个 Promise 对象,Promise 对象 reject 时则停止上传,resolve 时开始上传( resolve 传入 `File` 或 `Blob` 对象则上传 resolve 传入对象)。**注意:IE9 不支持该方法**。 | (file, fileList) => `boolean | Promise` | 无 |
|
| directory | 支持上传文件夹([caniuse](https://caniuse.com/#feat=input-file-directory)) | boolean | false | |
|
||||||
| customRequest | 通过覆盖默认的上传行为,可以自定义自己的上传实现 | Function | 无 |
|
| beforeUpload | 上传文件之前的钩子,参数为上传的文件,若返回 `false` 则停止上传。支持返回一个 Promise 对象,Promise 对象 reject 时则停止上传,resolve 时开始上传( resolve 传入 `File` 或 `Blob` 对象则上传 resolve 传入对象)。**注意:IE9 不支持该方法**。 | (file, fileList) => `boolean | Promise` | 无 | |
|
||||||
| data | 上传所需参数或返回上传参数的方法 | object\|(file) => object | 无 |
|
| customRequest | 通过覆盖默认的上传行为,可以自定义自己的上传实现 | Function | 无 | |
|
||||||
| defaultFileList | 默认已经上传的文件列表 | object\[] | 无 |
|
| data | 上传所需参数或返回上传参数的方法 | object\|(file) => object | 无 | |
|
||||||
| disabled | 是否禁用 | boolean | false |
|
| defaultFileList | 默认已经上传的文件列表 | object\[] | 无 | |
|
||||||
| fileList | 已经上传的文件列表(受控) | object\[] | 无 |
|
| disabled | 是否禁用 | boolean | false | |
|
||||||
| headers | 设置上传的请求头部,IE10 以上有效 | object | 无 |
|
| fileList | 已经上传的文件列表(受控) | object\[] | 无 | |
|
||||||
| listType | 上传列表的内建样式,支持三种基本样式 `text`, `picture` 和 `picture-card` | string | 'text' |
|
| headers | 设置上传的请求头部,IE10 以上有效 | object | 无 | |
|
||||||
| multiple | 是否支持多选文件,`ie10+` 支持。开启后按住 ctrl 可选择多个文件。 | boolean | false |
|
| listType | 上传列表的内建样式,支持三种基本样式 `text`, `picture` 和 `picture-card` | string | 'text' | |
|
||||||
| name | 发到后台的文件参数名 | string | 'file' |
|
| multiple | 是否支持多选文件,`ie10+` 支持。开启后按住 ctrl 可选择多个文件。 | boolean | false | |
|
||||||
| showUploadList | 是否展示 uploadList, 可设为一个对象,用于单独设定 showPreviewIcon 和 showRemoveIcon | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true |
|
| name | 发到后台的文件参数名 | string | 'file' | |
|
||||||
| supportServerRender | 服务端渲染时需要打开这个 | boolean | false |
|
| previewFile | 自定义文件预览逻辑 | (file: File \| Blob) => Promise<dataURL: string> | 无 | 1.5.0 |
|
||||||
| withCredentials | 上传请求时是否携带 cookie | boolean | false |
|
| showUploadList | 是否展示 uploadList, 可设为一个对象,用于单独设定 showPreviewIcon 和 showRemoveIcon | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | |
|
||||||
| openFileDialogOnClick | 点击打开文件对话框 | boolean | true |
|
| supportServerRender | 服务端渲染时需要打开这个 | boolean | false | |
|
||||||
| remove | 点击移除文件时的回调,返回值为 false 时不移除。支持返回一个 Promise 对象,Promise 对象 resolve(false) 或 reject 时不移除。 | Function(file): `boolean | Promise` | 无 |
|
| withCredentials | 上传请求时是否携带 cookie | boolean | false | |
|
||||||
|
| openFileDialogOnClick | 点击打开文件对话框 | boolean | true | |
|
||||||
|
| remove | 点击移除文件时的回调,返回值为 false 时不移除。支持返回一个 Promise 对象,Promise 对象 resolve(false) 或 reject 时不移除。 | Function(file): `boolean | Promise` | 无 | |
|
||||||
|
| transformFile | 在上传之前转换文件。支持返回一个 Promise 对象 | Function(file): `string | Blob | File | Promise<string | Blob | File>` | 无 | 1.5.0 |
|
||||||
|
|
||||||
### 事件
|
### 事件
|
||||||
|
|
||||||
| 事件名称 | 说明 | 回调参数 |
|
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||||
| -------- | -------------------------------------------- | ------------------ |
|
| --- | --- | --- | --- |
|
||||||
| change | 上传文件改变时的状态,详见 [change](#change) | Function | 无 |
|
| change | 上传文件改变时的状态,详见 [change](#change) | Function | 无 | |
|
||||||
| preview | 点击文件链接或预览图标时的回调 | Function(file) | 无 |
|
| preview | 点击文件链接或预览图标时的回调 | Function(file) | 无 | |
|
||||||
| reject | 拖拽文件不符合 accept 类型时的回调 | Function(fileList) | 无 |
|
| download | 点击下载文件时的回调,如果没有指定,则默认跳转到文件 url 对应的标签页。 | Function(file): void | 跳转新标签页 | 1.5.0 |
|
||||||
|
| reject | 拖拽文件不符合 accept 类型时的回调 | Function(fileList) | 无 | |
|
||||||
|
|
||||||
### change
|
### change
|
||||||
|
|
||||||
|
@ -48,10 +52,11 @@
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
uid: 'uid', // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突
|
uid: 'uid', // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突
|
||||||
name: 'xx.png' // 文件名
|
name: 'xx.png', // 文件名
|
||||||
status: 'done', // 状态有:uploading done error removed
|
status: 'done', // 状态有:uploading done error removed
|
||||||
response: '{"status": "success"}', // 服务端响应内容
|
response: '{"status": "success"}', // 服务端响应内容
|
||||||
linkProps: '{"download": "image"}', // 下载链接额外的 HTML 属性
|
linkProps: '{"download": "image"}', // 下载链接额外的 HTML 属性
|
||||||
|
xhr: 'XMLHttpRequest{ ... }', // XMLHttpRequest Header
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ export const ShowUploadListInterface = PropsTypes.shape({
|
||||||
export const UploadLocale = PropsTypes.shape({
|
export const UploadLocale = PropsTypes.shape({
|
||||||
uploading: PropsTypes.string,
|
uploading: PropsTypes.string,
|
||||||
removeFile: PropsTypes.string,
|
removeFile: PropsTypes.string,
|
||||||
|
downloadFile: PropsTypes.string,
|
||||||
uploadError: PropsTypes.string,
|
uploadError: PropsTypes.string,
|
||||||
previewFile: PropsTypes.string,
|
previewFile: PropsTypes.string,
|
||||||
}).loose;
|
}).loose;
|
||||||
|
@ -66,6 +67,7 @@ export const UploadProps = {
|
||||||
action: PropsTypes.oneOfType([PropsTypes.string, PropsTypes.func]),
|
action: PropsTypes.oneOfType([PropsTypes.string, PropsTypes.func]),
|
||||||
directory: PropsTypes.bool,
|
directory: PropsTypes.bool,
|
||||||
data: PropsTypes.oneOfType([PropsTypes.object, PropsTypes.func]),
|
data: PropsTypes.oneOfType([PropsTypes.object, PropsTypes.func]),
|
||||||
|
method: PropsTypes.oneOf(['POST', 'PUT', 'post', 'put']),
|
||||||
headers: PropsTypes.object,
|
headers: PropsTypes.object,
|
||||||
showUploadList: PropsTypes.oneOfType([PropsTypes.bool, ShowUploadListInterface]),
|
showUploadList: PropsTypes.oneOfType([PropsTypes.bool, ShowUploadListInterface]),
|
||||||
multiple: PropsTypes.bool,
|
multiple: PropsTypes.bool,
|
||||||
|
@ -86,6 +88,8 @@ export const UploadProps = {
|
||||||
locale: UploadLocale,
|
locale: UploadLocale,
|
||||||
height: PropsTypes.number,
|
height: PropsTypes.number,
|
||||||
id: PropsTypes.string,
|
id: PropsTypes.string,
|
||||||
|
previewFile: PropsTypes.func,
|
||||||
|
transformFile: PropsTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UploadState = {
|
export const UploadState = {
|
||||||
|
@ -103,6 +107,8 @@ export const UploadListProps = {
|
||||||
progressAttr: PropsTypes.object,
|
progressAttr: PropsTypes.object,
|
||||||
prefixCls: PropsTypes.string,
|
prefixCls: PropsTypes.string,
|
||||||
showRemoveIcon: PropsTypes.bool,
|
showRemoveIcon: PropsTypes.bool,
|
||||||
|
showDownloadIcon: PropsTypes.bool,
|
||||||
showPreviewIcon: PropsTypes.bool,
|
showPreviewIcon: PropsTypes.bool,
|
||||||
locale: UploadLocale,
|
locale: UploadLocale,
|
||||||
|
previewFile: PropsTypes.func,
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,3 +54,77 @@ export function removeFileItem(file, fileList) {
|
||||||
}
|
}
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== Default Image Preview ====================
|
||||||
|
const extname = (url = '') => {
|
||||||
|
const temp = url.split('/');
|
||||||
|
const filename = temp[temp.length - 1];
|
||||||
|
const filenameWithoutSuffix = filename.split(/#|\?/)[0];
|
||||||
|
return (/\.[^./\\]*$/.exec(filenameWithoutSuffix) || [''])[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
const isImageFileType = type => !!type && type.indexOf('image/') === 0;
|
||||||
|
|
||||||
|
export const isImageUrl = file => {
|
||||||
|
if (isImageFileType(file.type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const url = file.thumbUrl || file.url;
|
||||||
|
const extension = extname(url);
|
||||||
|
if (
|
||||||
|
/^data:image\//.test(url) ||
|
||||||
|
/(webp|svg|png|gif|jpg|jpeg|jfif|bmp|dpg|ico)$/i.test(extension)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (/^data:/.test(url)) {
|
||||||
|
// other file types of base64
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (extension) {
|
||||||
|
// other file types which have extension
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MEASURE_SIZE = 200;
|
||||||
|
export function previewImage(file) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
if (!isImageFileType(file.type)) {
|
||||||
|
resolve('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = MEASURE_SIZE;
|
||||||
|
canvas.height = MEASURE_SIZE;
|
||||||
|
canvas.style.cssText = `position: fixed; left: 0; top: 0; width: ${MEASURE_SIZE}px; height: ${MEASURE_SIZE}px; z-index: 9999; display: none;`;
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
const { width, height } = img;
|
||||||
|
|
||||||
|
let drawWidth = MEASURE_SIZE;
|
||||||
|
let drawHeight = MEASURE_SIZE;
|
||||||
|
let offsetX = 0;
|
||||||
|
let offsetY = 0;
|
||||||
|
|
||||||
|
if (width < height) {
|
||||||
|
drawHeight = height * (MEASURE_SIZE / width);
|
||||||
|
offsetY = -(drawHeight - drawWidth) / 2;
|
||||||
|
} else {
|
||||||
|
drawWidth = width * (MEASURE_SIZE / height);
|
||||||
|
offsetX = -(drawWidth - drawHeight) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.drawImage(img, offsetX, offsetY, drawWidth, drawHeight);
|
||||||
|
const dataURL = canvas.toDataURL();
|
||||||
|
document.body.removeChild(canvas);
|
||||||
|
|
||||||
|
resolve(dataURL);
|
||||||
|
};
|
||||||
|
img.src = window.URL.createObjectURL(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// rc-upload 2.6.3
|
// rc-upload 2.9.4
|
||||||
import upload from './src';
|
import upload from './src';
|
||||||
|
|
||||||
export default upload;
|
export default upload;
|
||||||
|
|
|
@ -28,6 +28,7 @@ const upLoadPropTypes = {
|
||||||
// onProgress: PropTypes.func,
|
// onProgress: PropTypes.func,
|
||||||
withCredentials: PropTypes.bool,
|
withCredentials: PropTypes.bool,
|
||||||
openFileDialogOnClick: PropTypes.bool,
|
openFileDialogOnClick: PropTypes.bool,
|
||||||
|
transformFile: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
const AjaxUploader = {
|
const AjaxUploader = {
|
||||||
|
@ -67,6 +68,7 @@ const AjaxUploader = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onFileDrop(e) {
|
onFileDrop(e) {
|
||||||
|
const { multiple } = this.$props;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (e.type === 'dragover') {
|
if (e.type === 'dragover') {
|
||||||
return;
|
return;
|
||||||
|
@ -76,21 +78,31 @@ const AjaxUploader = {
|
||||||
attrAccept(_file, this.accept),
|
attrAccept(_file, this.accept),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const files = partition(Array.prototype.slice.call(e.dataTransfer.files), file =>
|
let files = partition(Array.prototype.slice.call(e.dataTransfer.files), file =>
|
||||||
attrAccept(file, this.accept),
|
attrAccept(file, this.accept),
|
||||||
);
|
);
|
||||||
this.uploadFiles(files[0]);
|
let successFiles = files[0];
|
||||||
if (files[1].length) {
|
const errorFiles = files[1];
|
||||||
this.$emit('reject', files[1]);
|
if (multiple === false) {
|
||||||
|
successFiles = successFiles.slice(0, 1);
|
||||||
|
}
|
||||||
|
this.uploadFiles(successFiles);
|
||||||
|
|
||||||
|
if (errorFiles.length) {
|
||||||
|
this.$emit('reject', errorFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
uploadFiles(files) {
|
uploadFiles(files) {
|
||||||
const postFiles = Array.prototype.slice.call(files);
|
const postFiles = Array.prototype.slice.call(files);
|
||||||
postFiles.forEach(file => {
|
postFiles
|
||||||
file.uid = getUid();
|
.map(file => {
|
||||||
this.upload(file, postFiles);
|
file.uid = getUid();
|
||||||
});
|
return file;
|
||||||
|
})
|
||||||
|
.forEach(file => {
|
||||||
|
this.upload(file, postFiles);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
upload(file, fileList) {
|
upload(file, fileList) {
|
||||||
if (!this.beforeUpload) {
|
if (!this.beforeUpload) {
|
||||||
|
@ -119,10 +131,10 @@ const AjaxUploader = {
|
||||||
if (!this._isMounted) {
|
if (!this._isMounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let { data } = this.$props;
|
const { $props: props } = this;
|
||||||
if (typeof data === 'function') {
|
let { data } = props;
|
||||||
data = data(file);
|
const { transformFile = originFile => originFile } = props;
|
||||||
}
|
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
const { action } = this;
|
const { action } = this;
|
||||||
if (typeof action === 'function') {
|
if (typeof action === 'function') {
|
||||||
|
@ -132,26 +144,37 @@ const AjaxUploader = {
|
||||||
}).then(action => {
|
}).then(action => {
|
||||||
const { uid } = file;
|
const { uid } = file;
|
||||||
const request = this.customRequest || defaultRequest;
|
const request = this.customRequest || defaultRequest;
|
||||||
this.reqs[uid] = request({
|
const transform = Promise.resolve(transformFile(file)).catch(e => {
|
||||||
action,
|
console.error(e); // eslint-disable-line no-console
|
||||||
filename: this.name,
|
});
|
||||||
file,
|
transform.then(transformedFile => {
|
||||||
data,
|
if (typeof data === 'function') {
|
||||||
headers: this.headers,
|
data = data(file);
|
||||||
withCredentials: this.withCredentials,
|
}
|
||||||
onProgress: e => {
|
|
||||||
this.$emit('progress', e, file);
|
const requestOption = {
|
||||||
},
|
action,
|
||||||
onSuccess: (ret, xhr) => {
|
filename: this.name,
|
||||||
delete this.reqs[uid];
|
data,
|
||||||
this.$emit('success', ret, file, xhr);
|
file: transformedFile,
|
||||||
},
|
headers: this.headers,
|
||||||
onError: (err, ret) => {
|
withCredentials: this.withCredentials,
|
||||||
delete this.reqs[uid];
|
method: props.method || 'post',
|
||||||
this.$emit('error', err, ret, file);
|
onProgress: e => {
|
||||||
},
|
this.$emit('progress', e, file);
|
||||||
|
},
|
||||||
|
onSuccess: (ret, xhr) => {
|
||||||
|
delete this.reqs[uid];
|
||||||
|
this.$emit('success', ret, file, xhr);
|
||||||
|
},
|
||||||
|
onError: (err, ret) => {
|
||||||
|
delete this.reqs[uid];
|
||||||
|
this.$emit('error', err, ret, file);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.reqs[uid] = request(requestOption);
|
||||||
|
this.$emit('start', file);
|
||||||
});
|
});
|
||||||
this.$emit('start', file);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
reset() {
|
reset() {
|
||||||
|
@ -166,13 +189,13 @@ const AjaxUploader = {
|
||||||
if (file && file.uid) {
|
if (file && file.uid) {
|
||||||
uid = file.uid;
|
uid = file.uid;
|
||||||
}
|
}
|
||||||
if (reqs[uid]) {
|
if (reqs[uid] && reqs[uid].abort) {
|
||||||
reqs[uid].abort();
|
reqs[uid].abort();
|
||||||
delete reqs[uid];
|
|
||||||
}
|
}
|
||||||
|
delete reqs[uid];
|
||||||
} else {
|
} else {
|
||||||
Object.keys(reqs).forEach(uid => {
|
Object.keys(reqs).forEach(uid => {
|
||||||
if (reqs[uid]) {
|
if (reqs[uid] && reqs[uid].abort) {
|
||||||
reqs[uid].abort();
|
reqs[uid].abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +224,7 @@ const AjaxUploader = {
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
click: openFileDialogOnClick ? this.onClick : () => {},
|
click: openFileDialogOnClick ? this.onClick : () => {},
|
||||||
keydown: this.onKeyDown,
|
keydown: openFileDialogOnClick ? this.onKeyDown : () => {},
|
||||||
drop: this.onFileDrop,
|
drop: this.onFileDrop,
|
||||||
dragover: this.onFileDrop,
|
dragover: this.onFileDrop,
|
||||||
};
|
};
|
||||||
|
@ -222,6 +245,7 @@ const AjaxUploader = {
|
||||||
id={$attrs.id}
|
id={$attrs.id}
|
||||||
type="file"
|
type="file"
|
||||||
ref="fileInputRef"
|
ref="fileInputRef"
|
||||||
|
onClick={e => e.stopPropagation()} // https://github.com/ant-design/ant-design/issues/19948
|
||||||
key={this.uid}
|
key={this.uid}
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
accept={accept}
|
accept={accept}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
function getError(option, xhr) {
|
function getError(option, xhr) {
|
||||||
const msg = `cannot post ${option.action} ${xhr.status}'`;
|
const msg = `cannot ${option.method} ${option.action} ${xhr.status}'`;
|
||||||
const err = new Error(msg);
|
const err = new Error(msg);
|
||||||
err.status = xhr.status;
|
err.status = xhr.status;
|
||||||
err.method = 'post';
|
err.method = option.method;
|
||||||
err.url = option.action;
|
err.url = option.action;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,18 @@ export default function upload(option) {
|
||||||
const formData = new window.FormData();
|
const formData = new window.FormData();
|
||||||
|
|
||||||
if (option.data) {
|
if (option.data) {
|
||||||
Object.keys(option.data).map(key => {
|
Object.keys(option.data).forEach(key => {
|
||||||
|
const value = option.data[key];
|
||||||
|
// support key-value array data
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
value.forEach(item => {
|
||||||
|
// { list: [ 11, 22 ] }
|
||||||
|
// formData.append('list[]', 11);
|
||||||
|
formData.append(`${key}[]`, item);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
formData.append(key, option.data[key]);
|
formData.append(key, option.data[key]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -67,7 +78,7 @@ export default function upload(option) {
|
||||||
option.onSuccess(getBody(xhr), xhr);
|
option.onSuccess(getBody(xhr), xhr);
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.open('post', option.action, true);
|
xhr.open(option.method, option.action, true);
|
||||||
|
|
||||||
// Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179
|
// Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179
|
||||||
if (option.withCredentials && 'withCredentials' in xhr) {
|
if (option.withCredentials && 'withCredentials' in xhr) {
|
||||||
|
|
|
@ -27,6 +27,20 @@ const traverseFileTree = (files, callback, isAccepted) => {
|
||||||
if (item.isFile) {
|
if (item.isFile) {
|
||||||
item.file(file => {
|
item.file(file => {
|
||||||
if (isAccepted(file)) {
|
if (isAccepted(file)) {
|
||||||
|
// https://github.com/ant-design/ant-design/issues/16426
|
||||||
|
if (item.fullPath && !file.webkitRelativePath) {
|
||||||
|
Object.defineProperties(file, {
|
||||||
|
webkitRelativePath: {
|
||||||
|
writable: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
file.webkitRelativePath = item.fullPath.replace(/^\//, '');
|
||||||
|
Object.defineProperties(file, {
|
||||||
|
webkitRelativePath: {
|
||||||
|
writable: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
callback([file]);
|
callback([file]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,16 +4,54 @@
|
||||||
|
|
||||||
import { AntdComponent } from './component';
|
import { AntdComponent } from './component';
|
||||||
|
|
||||||
export interface UploadFile {
|
export interface VcFile extends File {
|
||||||
uid: string | number;
|
uid: string;
|
||||||
|
readonly lastModifiedDate: Date;
|
||||||
|
readonly webkitRelativePath: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UploadFile<T = any> {
|
||||||
|
uid: string;
|
||||||
|
size: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
fileName?: string;
|
||||||
|
lastModified?: number;
|
||||||
|
lastModifiedDate?: Date;
|
||||||
|
url?: string;
|
||||||
|
status?: UploadFileStatus;
|
||||||
|
percent?: number;
|
||||||
|
thumbUrl?: string;
|
||||||
|
originFileObj?: File | Blob;
|
||||||
|
response?: T;
|
||||||
|
error?: any;
|
||||||
|
linkProps?: any;
|
||||||
|
type: string;
|
||||||
|
xhr?: T;
|
||||||
|
preview?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShowUploadList {
|
export interface ShowUploadList {
|
||||||
showRemoveIcon?: boolean;
|
showRemoveIcon?: boolean;
|
||||||
showPreviewIcon?: boolean;
|
showPreviewIcon?: boolean;
|
||||||
|
showDownloadIcon?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UploadLocale {
|
||||||
|
uploading?: string;
|
||||||
|
removeFile?: string;
|
||||||
|
downloadFile?: string;
|
||||||
|
uploadError?: string;
|
||||||
|
previewFile?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UploadType = 'drag' | 'select';
|
||||||
|
export type UploadListType = 'text' | 'picture' | 'picture-card';
|
||||||
|
|
||||||
|
type PreviewFileHandler = (file: File | Blob) => PromiseLike<string>;
|
||||||
|
type TransformFileHandler = (
|
||||||
|
file: VcFile,
|
||||||
|
) => string | Blob | File | PromiseLike<string | Blob | File>;
|
||||||
|
|
||||||
export declare class Upload extends AntdComponent {
|
export declare class Upload extends AntdComponent {
|
||||||
static Dragger: typeof Upload;
|
static Dragger: typeof Upload;
|
||||||
|
|
||||||
|
@ -56,6 +94,8 @@ export declare class Upload extends AntdComponent {
|
||||||
*/
|
*/
|
||||||
data: object | Function;
|
data: object | Function;
|
||||||
|
|
||||||
|
method?: 'POST' | 'PUT' | 'post' | 'put';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default list of files that have been uploaded.
|
* Default list of files that have been uploaded.
|
||||||
* @type UploadFile[]
|
* @type UploadFile[]
|
||||||
|
@ -137,4 +177,9 @@ export declare class Upload extends AntdComponent {
|
||||||
* @type Function
|
* @type Function
|
||||||
*/
|
*/
|
||||||
remove: (file: any) => boolean | Promise<boolean>;
|
remove: (file: any) => boolean | Promise<boolean>;
|
||||||
|
|
||||||
|
locale?: UploadLocale;
|
||||||
|
id?: string;
|
||||||
|
previewFile?: PreviewFileHandler;
|
||||||
|
transformFile?: TransformFileHandler;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue