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;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: @image-placeholder-text-color;
|
color: @image-placeholder-text-color;
|
||||||
|
@ -6,6 +6,10 @@ import ImagePreview from '../image-preview';
|
|||||||
|
|
||||||
const [sfc, bem] = use('uploader');
|
const [sfc, bem] = use('uploader');
|
||||||
|
|
||||||
|
function isImageDataUrl(dataUrl) {
|
||||||
|
return dataUrl.indexOf('data:image') === 0;
|
||||||
|
}
|
||||||
|
|
||||||
export default sfc({
|
export default sfc({
|
||||||
inheritAttrs: false,
|
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({
|
ImagePreview({
|
||||||
images: this.fileList.map(file => file.content),
|
images: imageFiles,
|
||||||
startPosition
|
startPosition: imageFiles.indexOf(item.content)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -148,23 +156,33 @@ export default sfc({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.fileList.map((file, index) => (
|
return this.fileList.map((item, index) => (
|
||||||
<div class={bem('preview')}>
|
<div class={bem('preview')}>
|
||||||
<Image
|
<Image
|
||||||
fit="cover"
|
fit="cover"
|
||||||
src={file.content}
|
src={item.content}
|
||||||
class={bem('preview-image')}
|
class={bem('preview-image')}
|
||||||
width={this.previewSize}
|
width={this.previewSize}
|
||||||
height={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={() => {
|
onClick={() => {
|
||||||
this.onPreviewImage(index);
|
if (isImageDataUrl(item.content)) {
|
||||||
|
this.onPreviewImage(item);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Icon
|
<Icon
|
||||||
name="delete"
|
name="delete"
|
||||||
class={bem('preview-delete')}
|
class={bem('preview-delete')}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
this.onDelete(file, index);
|
this.onDelete(item, index);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -68,4 +68,19 @@
|
|||||||
background-color: @uploader-delete-background-color;
|
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">
|
||||||
<div class="van-uploader__wrapper">
|
<div class="van-uploader__wrapper">
|
||||||
<div class="van-uploader__preview">
|
<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;">
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
|
||||||
<!----></i></div>
|
<!----></i></div>
|
||||||
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
|
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
|
||||||
@ -32,11 +32,29 @@ exports[`max-count prop 1`] = `
|
|||||||
</div>
|
</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`] = `
|
exports[`preview-size prop 1`] = `
|
||||||
<div class="van-uploader">
|
<div class="van-uploader">
|
||||||
<div class="van-uploader__wrapper">
|
<div class="van-uploader__wrapper">
|
||||||
<div class="van-uploader__preview" style="">
|
<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;">
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
|
||||||
<!----></i></div>
|
<!----></i></div>
|
||||||
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
|
</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">
|
||||||
<div class="van-uploader__wrapper">
|
<div class="van-uploader__wrapper">
|
||||||
<div class="van-uploader__preview">
|
<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;">
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 22px;">
|
||||||
<!----></i></div>
|
<!----></i></div>
|
||||||
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
|
</div><i class="van-icon van-icon-delete van-uploader__preview-delete">
|
||||||
|
@ -5,22 +5,23 @@ window.File = function () {
|
|||||||
this.size = 10000;
|
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 () {
|
window.FileReader = function () {
|
||||||
this.readAsText = function () {
|
this.readAsText = function () {
|
||||||
this.onload &&
|
this.onload &&
|
||||||
this.onload({
|
this.onload({
|
||||||
target: {
|
target: {
|
||||||
result: 'test'
|
result: mockFileDataUrl
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.readAsDataURL = this.readAsText;
|
this.readAsDataURL = this.readAsText;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockFile = new File([], '/Users');
|
|
||||||
const file = { target: { files: [mockFile] } };
|
|
||||||
const multiFile = { target: { files: [mockFile, mockFile] } };
|
|
||||||
|
|
||||||
test('disabled', () => {
|
test('disabled', () => {
|
||||||
const afterRead = jest.fn();
|
const afterRead = jest.fn();
|
||||||
const wrapper = mount(Uploader, {
|
const wrapper = mount(Uploader, {
|
||||||
@ -39,7 +40,7 @@ it('read text', done => {
|
|||||||
propsData: {
|
propsData: {
|
||||||
resultType: 'text',
|
resultType: 'text',
|
||||||
afterRead: readFile => {
|
afterRead: readFile => {
|
||||||
expect(readFile.content).toEqual('test');
|
expect(readFile.content).toEqual(mockFileDataUrl);
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,5 +277,26 @@ it('click to preview image', async () => {
|
|||||||
|
|
||||||
wrapper.find('.van-image').trigger('click');
|
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