mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[new feature] Uploader: support preview non-image file (#3604)
This commit is contained in:
parent
a27df2c25f
commit
dea0d28361
@ -18,6 +18,7 @@
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: @image-placeholder-text-color;
|
||||
|
@ -6,6 +6,10 @@ import ImagePreview from '../image-preview';
|
||||
|
||||
const [sfc, bem] = use('uploader');
|
||||
|
||||
function isImageDataUrl(dataUrl) {
|
||||
return dataUrl.indexOf('data:image') === 0;
|
||||
}
|
||||
|
||||
export default sfc({
|
||||
inheritAttrs: false,
|
||||
|
||||
@ -136,10 +140,14 @@ export default sfc({
|
||||
}
|
||||
},
|
||||
|
||||
onPreviewImage(startPosition) {
|
||||
onPreviewImage(item) {
|
||||
const imageFiles = this.fileList
|
||||
.map(item => item.content)
|
||||
.filter(content => isImageDataUrl(content));
|
||||
|
||||
ImagePreview({
|
||||
images: this.fileList.map(file => file.content),
|
||||
startPosition
|
||||
images: imageFiles,
|
||||
startPosition: imageFiles.indexOf(item.content)
|
||||
});
|
||||
},
|
||||
|
||||
@ -148,23 +156,33 @@ export default sfc({
|
||||
return;
|
||||
}
|
||||
|
||||
return this.fileList.map((file, index) => (
|
||||
return this.fileList.map((item, index) => (
|
||||
<div class={bem('preview')}>
|
||||
<Image
|
||||
fit="cover"
|
||||
src={file.content}
|
||||
src={item.content}
|
||||
class={bem('preview-image')}
|
||||
width={this.previewSize}
|
||||
height={this.previewSize}
|
||||
scopedSlots={{
|
||||
error() {
|
||||
return [
|
||||
<Icon class={bem('file-icon')} name="description" />,
|
||||
<div class={[bem('file-name'), 'van-ellipsis']}>{item.file.name}</div>
|
||||
];
|
||||
}
|
||||
}}
|
||||
onClick={() => {
|
||||
this.onPreviewImage(index);
|
||||
if (isImageDataUrl(item.content)) {
|
||||
this.onPreviewImage(item);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Icon
|
||||
name="delete"
|
||||
class={bem('preview-delete')}
|
||||
onClick={() => {
|
||||
this.onDelete(file, index);
|
||||
this.onDelete(item, index);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -68,4 +68,19 @@
|
||||
background-color: @uploader-delete-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
&__file-icon {
|
||||
color: @gray-darker;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
&__file-name {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
padding: 0 5px;
|
||||
color: @gray-darker;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ exports[`max-count prop 1`] = `
|
||||
<div class="van-uploader">
|
||||
<div class="van-uploader__wrapper">
|
||||
<div class="van-uploader__preview">
|
||||
<div class="van-image van-uploader__preview-image"><img src="test" class="van-image__img" style="object-fit: cover;">
|
||||
<div class="van-image van-uploader__preview-image"><img src="data:image/test" class="van-image__img" style="object-fit: cover;">
|
||||
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
|
||||
<!----></i></div>
|
||||
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
|
||||
@ -32,11 +32,29 @@ exports[`max-count prop 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`preview not image file 1`] = `
|
||||
<div class="van-uploader">
|
||||
<div class="van-uploader__wrapper">
|
||||
<div class="van-uploader__preview">
|
||||
<div class="van-image van-uploader__preview-image">
|
||||
<div class="van-image__error"><i class="van-icon van-icon-description van-uploader__file-icon" style="">
|
||||
<!----></i>
|
||||
<div class="van-uploader__file-name van-ellipsis">test.md</div>
|
||||
</div>
|
||||
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
|
||||
<!----></i>
|
||||
</div>
|
||||
<div class="van-uploader__upload"><i class="van-icon van-icon-plus van-uploader__upload-icon">
|
||||
<!----></i><input type="file" accept="image/*" class="van-uploader__input"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`preview-size prop 1`] = `
|
||||
<div class="van-uploader">
|
||||
<div class="van-uploader__wrapper">
|
||||
<div class="van-uploader__preview" style="">
|
||||
<div class="van-image van-uploader__preview-image" style="width: 30px; height: 30px;"><img src="test" class="van-image__img" style="object-fit: cover;">
|
||||
<div class="van-image van-uploader__preview-image" style="width: 30px; height: 30px;"><img src="data:image/test" class="van-image__img" style="object-fit: cover;">
|
||||
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
|
||||
<!----></i></div>
|
||||
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
|
||||
@ -52,7 +70,7 @@ exports[`render preview image 1`] = `
|
||||
<div class="van-uploader">
|
||||
<div class="van-uploader__wrapper">
|
||||
<div class="van-uploader__preview">
|
||||
<div class="van-image van-uploader__preview-image"><img src="test" class="van-image__img" style="object-fit: cover;">
|
||||
<div class="van-image van-uploader__preview-image"><img src="data:image/test" class="van-image__img" style="object-fit: cover;">
|
||||
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
|
||||
<!----></i></div>
|
||||
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
|
||||
|
@ -5,22 +5,23 @@ window.File = function () {
|
||||
this.size = 10000;
|
||||
};
|
||||
|
||||
const mockFileDataUrl = 'data:image/test';
|
||||
const mockFile = new File([], '/Users');
|
||||
const file = { target: { files: [mockFile] } };
|
||||
const multiFile = { target: { files: [mockFile, mockFile] } };
|
||||
|
||||
window.FileReader = function () {
|
||||
this.readAsText = function () {
|
||||
this.onload &&
|
||||
this.onload({
|
||||
target: {
|
||||
result: 'test'
|
||||
result: mockFileDataUrl
|
||||
}
|
||||
});
|
||||
};
|
||||
this.readAsDataURL = this.readAsText;
|
||||
};
|
||||
|
||||
const mockFile = new File([], '/Users');
|
||||
const file = { target: { files: [mockFile] } };
|
||||
const multiFile = { target: { files: [mockFile, mockFile] } };
|
||||
|
||||
test('disabled', () => {
|
||||
const afterRead = jest.fn();
|
||||
const wrapper = mount(Uploader, {
|
||||
@ -39,7 +40,7 @@ it('read text', done => {
|
||||
propsData: {
|
||||
resultType: 'text',
|
||||
afterRead: readFile => {
|
||||
expect(readFile.content).toEqual('test');
|
||||
expect(readFile.content).toEqual(mockFileDataUrl);
|
||||
done();
|
||||
}
|
||||
}
|
||||
@ -276,5 +277,26 @@ it('click to preview image', async () => {
|
||||
|
||||
wrapper.find('.van-image').trigger('click');
|
||||
|
||||
expect(document.querySelector('.van-image-preview')).toBeTruthy();
|
||||
const imagePreviewNode = document.querySelector('.van-image-preview');
|
||||
expect(imagePreviewNode).toBeTruthy();
|
||||
imagePreviewNode.remove();
|
||||
});
|
||||
|
||||
it('preview not image file', async () => {
|
||||
const wrapper = mount(Uploader, {
|
||||
propsData: {
|
||||
fileList: [{
|
||||
content: 'data:application',
|
||||
file: {
|
||||
name: 'test.md'
|
||||
}
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
wrapper.find('img').trigger('error');
|
||||
wrapper.find('.van-image').trigger('click');
|
||||
|
||||
expect(document.querySelector('.van-image-preview')).toBeFalsy();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user