You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ant-design-vue/components/upload/Upload.jsx

304 lines
7.7 KiB

7 years ago
import classNames from 'classnames'
import uniqBy from 'lodash/uniqBy'
import VcUpload from '../vc-upload'
import BaseMixin from '../_util/BaseMixin'
import { getOptionProps, initDefaultProps, hasProp } from '../_util/props-util'
import LocaleReceiver from '../locale-provider/LocaleReceiver'
import defaultLocale from '../locale-provider/default'
import Dragger from './Dragger'
import UploadList from './UploadList'
import { UploadProps } from './interface'
import { T, fileToObject, genPercentAdd, getFileItem, removeFileItem } from './utils'
export { UploadProps }
export default {
inheritAttrs: false,
7 years ago
name: 'AUpload',
Dragger: Dragger,
mixins: [BaseMixin],
props: initDefaultProps(UploadProps, {
prefixCls: 'ant-upload',
type: 'select',
multiple: false,
action: '',
data: {},
accept: '',
beforeUpload: T,
showUploadList: true,
listType: 'text', // or pictrue
disabled: false,
supportServerRender: true,
}),
// recentUploadStatus: boolean | PromiseLike<any>;
data () {
this.progressTimer = null
return {
sFileList: this.fileList || this.defaultFileList || [],
dragState: 'drop',
}
},
beforeDestroy () {
this.clearProgressTimer()
},
watch: {
fileList (val) {
this.sFileList = val
},
},
methods: {
onStart (file) {
const targetItem = fileToObject(file)
targetItem.status = 'uploading'
const nextFileList = this.sFileList.concat()
const fileIndex = nextFileList.findIndex(({ uid }) => uid === targetItem.uid)
if (fileIndex === -1) {
nextFileList.push(targetItem)
} else {
nextFileList[fileIndex] = targetItem
}
7 years ago
this.onChange({
file: targetItem,
fileList: nextFileList,
})
// fix ie progress
if (!window.FormData) {
this.autoUpdateProgress(0, targetItem)
}
},
autoUpdateProgress (_, file) {
const getPercent = genPercentAdd()
let curPercent = 0
this.clearProgressTimer()
this.progressTimer = setInterval(() => {
curPercent = getPercent(curPercent)
this.onProgress({
update to antd3.8.3 (#159) * refactor: align * feat: update align to 2.4.3 * feat: update trigger 2.5.4 * feat: update tooltip 3.7.2 * fix: align * feat: update vc-calendar to 9.6.2 * feat: update vc-checkbox to 2.1.5 * feat: update vc-dialog to 7.1.8 * feat: update vc-from to 2.2.1 * feat: update vc-notification to 3.1.1 * test: update snapshots * feat: update vc-tree to 1.12.6 * feat: update vc-table to 6.2.8 * feat: update vc-upload to 2.5.1 * feat: update vc-input-number to 4.0.12 * feat: update vc-tabs to 9.2.6 * refactor: vc-menu * refactor: update vc-menu to 7.0.5 * style: remove unused * feat: update pagination to 1.16.5 * feat: add vc-progress 2.2.5 tag * feat: add vc-rate 2.4.0 tag * feat: update vc-slider to 8.6.1 * fix: tooltip error * style: delete conosle * feat: update vc-steps to 3.1.1 * add vc-switch tag 1.6.0 * feat: update upload to 2.5.1 * fix: update vc-menu * fix: update store * fix: add ref dir * fix: trigger mock shouldComponentUpdate * fix: update vc-select * revert: trigger lazyrenderbox * fix: update vc-select * fix: update vc-select * fix: update vc-select * fix: update vc-menu * fix: update vc-slick ref * update style to 3.8.2 * test: update snapshots * update vc-select * update util & affix * feat: add drawer * fix: support title add slot mode * test: update affix test * update alert * update anchor * update snapshots * fix: doc and vc-drawer * update select & auto-complete * update back-top & grid * feractor: avatar * test: add drawer test * update badge * update button * update card * update divider * feat: update vc-tabs to 9.3.6 and tabs * add afterEnter callback * update form * fix: update drawer * test: update snapshots * update modal & notification * test: update snapshots * update message * update locale-provider * update dropdown * update layout popconfirm popover * update time-picker * update menu * update date-picker * docs: update input docs * update input * update snapshots * update table * update test snapshots * feat: update progress * update checkbox * feat: update spin * update radio * docs: slider steps timeline * update list * update transfer * update collapse * update cascader * update upload
6 years ago
percent: curPercent * 100,
7 years ago
}, file)
}, 200)
},
onSuccess (response, file) {
this.clearProgressTimer()
try {
if (typeof response === 'string') {
response = JSON.parse(response)
}
} catch (e) { /* do nothing */
}
const fileList = this.sFileList
const targetItem = getFileItem(file, fileList)
// removed
if (!targetItem) {
return
}
targetItem.status = 'done'
targetItem.response = response
this.onChange({
file: { ...targetItem },
fileList,
})
},
onProgress (e, file) {
const fileList = this.sFileList
const targetItem = getFileItem(file, fileList)
// removed
if (!targetItem) {
return
}
targetItem.percent = e.percent
this.onChange({
event: e,
file: { ...targetItem },
fileList: this.sFileList,
})
},
onError (error, response, file) {
this.clearProgressTimer()
const fileList = this.sFileList
const targetItem = getFileItem(file, fileList)
// removed
if (!targetItem) {
return
}
targetItem.error = error
targetItem.response = response
targetItem.status = 'error'
this.onChange({
file: { ...targetItem },
fileList,
})
},
handleRemove (file) {
const { remove } = getOptionProps(this)
Promise.resolve(typeof remove === 'function' ? remove(file) : remove).then(ret => {
7 years ago
// Prevent removing file
if (ret === false) {
return
}
const removedFileList = removeFileItem(file, this.sFileList)
if (removedFileList) {
this.onChange({
file,
fileList: removedFileList,
})
}
})
},
handleManualRemove (file) {
this.$refs.uploadRef.abort(file)
file.status = 'removed' // eslint-disable-line
this.handleRemove(file)
},
onChange (info) {
if (!hasProp(this, 'fileList')) {
this.setState({ sFileList: info.fileList })
}
this.$emit('change', info)
},
onFileDrop (e) {
this.setState({
dragState: e.type,
})
},
reBeforeUpload (file, fileList) {
if (!this.beforeUpload) {
return true
}
const result = this.beforeUpload(file, fileList)
if (result === false) {
this.onChange({
file,
update to antd3.8.3 (#159) * refactor: align * feat: update align to 2.4.3 * feat: update trigger 2.5.4 * feat: update tooltip 3.7.2 * fix: align * feat: update vc-calendar to 9.6.2 * feat: update vc-checkbox to 2.1.5 * feat: update vc-dialog to 7.1.8 * feat: update vc-from to 2.2.1 * feat: update vc-notification to 3.1.1 * test: update snapshots * feat: update vc-tree to 1.12.6 * feat: update vc-table to 6.2.8 * feat: update vc-upload to 2.5.1 * feat: update vc-input-number to 4.0.12 * feat: update vc-tabs to 9.2.6 * refactor: vc-menu * refactor: update vc-menu to 7.0.5 * style: remove unused * feat: update pagination to 1.16.5 * feat: add vc-progress 2.2.5 tag * feat: add vc-rate 2.4.0 tag * feat: update vc-slider to 8.6.1 * fix: tooltip error * style: delete conosle * feat: update vc-steps to 3.1.1 * add vc-switch tag 1.6.0 * feat: update upload to 2.5.1 * fix: update vc-menu * fix: update store * fix: add ref dir * fix: trigger mock shouldComponentUpdate * fix: update vc-select * revert: trigger lazyrenderbox * fix: update vc-select * fix: update vc-select * fix: update vc-select * fix: update vc-menu * fix: update vc-slick ref * update style to 3.8.2 * test: update snapshots * update vc-select * update util & affix * feat: add drawer * fix: support title add slot mode * test: update affix test * update alert * update anchor * update snapshots * fix: doc and vc-drawer * update select & auto-complete * update back-top & grid * feractor: avatar * test: add drawer test * update badge * update button * update card * update divider * feat: update vc-tabs to 9.3.6 and tabs * add afterEnter callback * update form * fix: update drawer * test: update snapshots * update modal & notification * test: update snapshots * update message * update locale-provider * update dropdown * update layout popconfirm popover * update time-picker * update menu * update date-picker * docs: update input docs * update input * update snapshots * update table * update test snapshots * feat: update progress * update checkbox * feat: update spin * update radio * docs: slider steps timeline * update list * update transfer * update collapse * update cascader * update upload
6 years ago
fileList: uniqBy(
this.sFileList.concat(fileList.map(fileToObject)),
(item) => item.uid,
),
7 years ago
})
return false
} else if (result && result.then) {
return result
}
return true
},
clearProgressTimer () {
clearInterval(this.progressTimer)
},
renderUploadList (locale) {
const { showUploadList = {}, listType } = getOptionProps(this)
const { showRemoveIcon, showPreviewIcon } = showUploadList
const uploadListProps = {
props: {
listType,
items: this.sFileList,
showRemoveIcon,
showPreviewIcon,
locale: { ...locale, ...this.$props.locale },
},
on: {
remove: this.handleManualRemove,
},
}
if (this.$listeners.preview) {
uploadListProps.on.preview = this.$listeners.preview
}
7 years ago
return (
<UploadList
{...uploadListProps}
/>
)
},
},
render () {
const {
prefixCls = '',
showUploadList,
listType,
type,
disabled,
} = getOptionProps(this)
const vcUploadProps = {
props: {
...this.$props,
beforeUpload: this.reBeforeUpload,
},
on: {
// ...this.$listeners,
start: this.onStart,
error: this.onError,
progress: this.onProgress,
success: this.onSuccess,
},
ref: 'uploadRef',
class: `${prefixCls}-btn`,
attrs: this.$attrs,
7 years ago
}
const uploadList = showUploadList ? (
<LocaleReceiver
componentName='Upload'
defaultLocale={defaultLocale.Upload}
scopedSlots={
{ default: this.renderUploadList }
}
7 years ago
>
</LocaleReceiver>
) : null
const children = this.$slots.default
if (type === 'drag') {
const dragCls = classNames(prefixCls, {
[`${prefixCls}-drag`]: true,
[`${prefixCls}-drag-uploading`]: this.sFileList.some(file => file.status === 'uploading'),
[`${prefixCls}-drag-hover`]: this.dragState === 'dragover',
[`${prefixCls}-disabled`]: disabled,
})
return (
<span>
<div
class={dragCls}
onDrop={this.onFileDrop}
onDragover={this.onFileDrop}
onDragleave={this.onFileDrop}
>
<VcUpload {...vcUploadProps}>
<div class={`${prefixCls}-drag-container`}>
{children}
</div>
</VcUpload>
</div>
{uploadList}
</span>
)
}
const uploadButtonCls = classNames(prefixCls, {
[`${prefixCls}-select`]: true,
[`${prefixCls}-select-${listType}`]: true,
[`${prefixCls}-disabled`]: disabled,
})
const uploadButton = (
<div class={uploadButtonCls} style={{ display: children ? '' : 'none' }}>
<VcUpload {...vcUploadProps} >{children}</VcUpload>
</div>
)
if (listType === 'picture-card') {
return (
<span>
{uploadList}
{uploadButton}
</span>
)
}
return (
<span>
{uploadButton}
{uploadList}
</span>
)
},
}