feat: update upload

pull/309/head
wangxueliang 2018-12-05 18:31:58 +08:00
parent e51a6e9691
commit 44d55b329d
9 changed files with 77 additions and 12 deletions

View File

@ -48,10 +48,15 @@ export default {
},
methods: {
onStart (file) {
const nextFileList = this.sFileList.concat()
const targetItem = fileToObject(file)
targetItem.status = 'uploading'
nextFileList.push(targetItem)
const nextFileList = this.sFileList.concat()
const fileIndex = nextFileList.findIndex(({ uid }) => uid === targetItem.uid)
if (fileIndex === -1) {
nextFileList.push(targetItem)
} else {
nextFileList[fileIndex] = targetItem
}
this.onChange({
file: targetItem,
fileList: nextFileList,

View File

@ -7,8 +7,12 @@ import Progress from '../progress'
import classNames from 'classnames'
import { UploadListProps } from './interface'
const imageTypes = ['image', 'webp', 'png', 'svg', 'gif', 'jpg', 'jpeg', 'bmp']
// 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)
@ -23,7 +27,7 @@ const extname = (url) => {
const filenameWithoutSuffix = filename.split(/#|\?/)[0]
return (/\.[^./\\]*$/.exec(filenameWithoutSuffix) || [''])[0]
}
const imageTypes = ['image', 'webp', 'png', 'svg', 'gif', 'jpg', 'jpeg', 'bmp']
const isImageUrl = (file) => {
if (imageTypes.includes(file.type)) {
return true
@ -148,15 +152,17 @@ export default {
[`${prefixCls}-list-item`]: true,
[`${prefixCls}-list-item-${file.status}`]: true,
})
const linkProps = typeof file.linkProps === 'string'
? JSON.parse(file.linkProps) : file.linkProps
const preview = file.url ? (
<a
{...file.linkProps}
href={file.url}
target='_blank'
rel='noopener noreferrer'
class={`${prefixCls}-list-item-name`}
onClick={e => this.handlePreview(file, e)}
title={file.name}
{...linkProps}
href={file.url}
onClick={e => this.handlePreview(file, e)}
>
{file.name}
</a>
@ -196,16 +202,16 @@ export default {
}
},
}
const iconProps1 = {...iconProps, ...{props: {type: 'cross'}}}
const iconProps1 = {...iconProps, ...{props: {type: 'close'}}}
const removeIcon = showRemoveIcon ? (
<Icon {...iconProps} />
) : null
const removeIconCross = showRemoveIcon ? (
const removeIconClose = showRemoveIcon ? (
<Icon {...iconProps1}/>
) : null
const actions = (listType === 'picture-card' && file.status !== 'uploading')
? <span class={`${prefixCls}-list-item-actions`}>{previewIcon}{removeIcon}</span>
: removeIconCross
: removeIconClose
let message
if (file.response && typeof file.response === 'string') {
message = file.response

View File

@ -176,4 +176,55 @@ describe('Upload', () => {
})
})
})
it('should support linkProps as object', () => {
const fileList = [{
uid: '-1',
name: 'foo.png',
status: 'done',
url: 'http://www.baidu.com/xxx.png',
linkProps: {
download: 'image',
rel: 'noopener',
},
}]
const props = {
propsData: {
fileList,
},
sync: false,
}
const wrapper = mount(Upload, props)
setTimeout(() => {
const linkNode = wrapper.find('a.ant-upload-list-item-name')
expect(linkNode.props().download).toBe('image')
expect(linkNode.props().rel).toBe('noopener')
}, 0)
})
it('should support linkProps as json stringify', () => {
const linkPropsString = JSON.stringify({
download: 'image',
rel: 'noopener',
})
const fileList = [{
uid: '-1',
name: 'foo.png',
status: 'done',
url: 'http://www.baidu.com/xxx.png',
linkProps: linkPropsString,
}]
const props = {
propsData: {
fileList,
},
sync: false,
}
const wrapper = mount(Upload, props)
setTimeout(() => {
const linkNode = wrapper.find('a.ant-upload-list-item-name')
expect(linkNode.props().download).toBe('image')
expect(linkNode.props().rel).toBe('noopener')
}, 0)
})
})

View File

@ -76,7 +76,7 @@ describe('Upload List', () => {
const wrapper = mount(Upload, props)
setTimeout(async () => {
expect(wrapper.findAll('.ant-upload-list-item').length).toBe(2)
wrapper.findAll('.ant-upload-list-item').at(0).find('.anticon-cross').trigger('click')
wrapper.findAll('.ant-upload-list-item').at(0).find('.anticon-close').trigger('click')
await delay(400)
// wrapper.update();
expect(wrapper.findAll('.ant-upload-list-item').length).toBe(1)

View File

@ -1,7 +1,7 @@
<cn>
#### 用户头像
点击上传用户头像,并使用 `beforeUpload` 限制用户上传的图片格式和大小。
`beforeUpload` 的返回值可以是一个 Promise 以支持也支持异步检查
`beforeUpload` 的返回值可以是一个 Promise 以支持异步处理,如服务端校验等
</cn>
<us>

View File

@ -20,6 +20,7 @@
| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon` and `showRemoveIcon` individually | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true |
| supportServerRender | Need to be turned on while the server side is rendering. | boolean | false |
| 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` | - |
### events

View File

@ -20,6 +20,7 @@
| showUploadList | 是否展示 uploadList, 可设为一个对象,用于单独设定 showPreviewIcon 和 showRemoveIcon | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true |
| supportServerRender | 服务端渲染时需要打开这个 | boolean | false |
| withCredentials | 上传请求时是否携带 cookie | boolean | false |
| openFileDialogOnClick | 点击打开文件对话框 | boolean | true |
| remove   | 点击移除文件时的回调,返回值为 false 时不移除。支持返回一个 Promise 对象Promise 对象 resolve(false) 或 reject 时不移除。               | Function(file): `boolean | Promise` | 无   |
### 事件

View File

@ -76,6 +76,7 @@ export const UploadProps = {
prefixCls: PropsTypes.string,
customRequest: PropsTypes.func,
withCredentials: PropsTypes.bool,
openFileDialogOnClick: PropsTypes.bool,
locale: UploadLocale,
height: PropsTypes.number,
}

View File

@ -11,7 +11,7 @@ import Api from './components/api'
import './components'
import demoBox from './components/demoBox'
import demoContainer from './components/demoContainer'
import Test from '../components/avatar/demo/index'
import Test from '../components/test/index.vue'
import zhCN from './theme/zh-CN'
import enUS from './theme/en-US'
Vue.use(VueClipboard)