feat(ImagePreview): add image loading tip (#4378)

This commit is contained in:
neverland 2019-09-05 17:48:08 +08:00 committed by GitHub
parent b9c1dca67c
commit 3f8ffccb36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 138 additions and 94 deletions

View File

@ -4,6 +4,8 @@ import { preventDefault } from '../utils/dom/event';
import { PopupMixin } from '../mixins/popup';
import { TouchMixin } from '../mixins/touch';
import { CloseOnPopstateMixin } from '../mixins/close-on-popstate';
import Image from '../image';
import Loading from '../loading';
import Swipe from '../swipe';
import SwipeItem from '../swipe-item';
@ -19,11 +21,7 @@ function getDistance(touches) {
}
export default createComponent({
mixins: [
PopupMixin,
TouchMixin,
CloseOnPopstateMixin
],
mixins: [PopupMixin, TouchMixin, CloseOnPopstateMixin],
props: {
className: null,
@ -253,6 +251,51 @@ export default createComponent({
this.scale = scale;
this.moveX = 0;
this.moveY = 0;
},
genIndex() {
if (this.showIndex) {
return (
<div class={bem('index')}>
{this.slots('index') || `${this.active + 1}/${this.images.length}`}
</div>
);
}
},
genImages() {
const imageSlots = {
loading: () => <Loading type="spinner" />
};
return (
<Swipe
ref="swipe"
loop={this.loop}
duration={this.swipeDuration}
indicatorColor="white"
initialSwipe={this.startPosition}
showIndicators={this.showIndicators}
onChange={this.setActive}
>
{this.images.map((image, index) => (
<SwipeItem>
<Image
src={image}
fit="contain"
class={bem('image')}
lazyLoad={this.lazyLoad}
scopedSlots={imageSlots}
style={index === this.active ? this.imageStyle : null}
nativeOnTouchstart={this.onImageTouchStart}
nativeOnTouchmove={this.onImageTouchMove}
nativeOnTouchend={this.onImageTouchEnd}
nativeOnTouchcancel={this.onImageTouchEnd}
/>
</SwipeItem>
))}
</Swipe>
);
}
},
@ -261,48 +304,6 @@ export default createComponent({
return;
}
const { active, images } = this;
const Index = this.showIndex && (
<div class={bem('index')}>
{this.slots('index') || `${active + 1}/${images.length}`}
</div>
);
const Images = (
<Swipe
ref="swipe"
loop={this.loop}
duration={this.swipeDuration}
indicatorColor="white"
initialSwipe={this.startPosition}
showIndicators={this.showIndicators}
onChange={this.setActive}
>
{images.map((image, index) => {
const props = {
class: bem('image'),
style: index === active ? this.imageStyle : null,
on: {
touchstart: this.onImageTouchStart,
touchmove: this.onImageTouchMove,
touchend: this.onImageTouchEnd,
touchcancel: this.onImageTouchEnd
}
};
return (
<SwipeItem>
{this.lazyLoad ? (
<img vLazy={image} {...props} />
) : (
<img src={image} {...props} />
)}
</SwipeItem>
);
})}
</Swipe>
);
return (
<transition name="van-fade">
<div
@ -312,8 +313,8 @@ export default createComponent({
onTouchend={this.onWrapperTouchEnd}
onTouchcancel={this.onWrapperTouchEnd}
>
{Images}
{Index}
{this.genImages()}
{this.genIndex()}
</div>
</transition>
);

View File

@ -94,6 +94,7 @@ export default {
showImagePreview(position, timer) {
const instance = ImagePreview({
images,
lazyLoad: true,
swipeDuration: 300,
asyncClose: !!timer,
closeOnPopstate: true,

View File

@ -13,9 +13,10 @@
right: 0;
bottom: 0;
left: 0;
max-width: 100%;
max-height: 100%;
margin: auto;
.van-image__loading {
background-color: transparent;
}
}
&__index {

View File

@ -13,9 +13,27 @@ exports[`lazy-load prop 1`] = `
<div class="van-image-preview" name="van-fade">
<div class="van-swipe">
<div class="van-swipe__track" style="width: 0px; transition-duration: 0ms; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img class="van-image-preview__image" style="transition: .3s all;"></div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img class="van-image-preview__image"></div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img class="van-image-preview__image"></div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
<div class="van-image van-image-preview__image" style="transition: .3s all;"><img class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading">
<div class="van-loading van-loading--spinner"><span class="van-loading__spinner van-loading__spinner--spinner" style="color: rgb(201, 201, 201);"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
</div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
<div class="van-image van-image-preview__image"><img class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading">
<div class="van-loading van-loading--spinner"><span class="van-loading__spinner van-loading__spinner--spinner" style="color: rgb(201, 201, 201);"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
</div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
<div class="van-image van-image-preview__image"><img class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading">
<div class="van-loading van-loading--spinner"><span class="van-loading__spinner van-loading__spinner--spinner" style="color: rgb(201, 201, 201);"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
</div>
</div>
</div>
<div class="van-image-preview__index">1/3</div>
@ -26,22 +44,66 @@ exports[`render image 1`] = `
<div class="van-image-preview" name="van-fade">
<div class="van-swipe">
<div class="van-swipe__track" style="width: 0px; transition-duration: 500ms; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img src="https://img.yzcdn.cn/1.png" class="van-image-preview__image" style="transition: .3s all;"></div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img src="https://img.yzcdn.cn/2.png" class="van-image-preview__image"></div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img src="https://img.yzcdn.cn/3.png" class="van-image-preview__image"></div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
<div class="van-image van-image-preview__image" style="transition: .3s all;"><img src="https://img.yzcdn.cn/1.png" class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading">
<div class="van-loading van-loading--spinner"><span class="van-loading__spinner van-loading__spinner--spinner" style="color: rgb(201, 201, 201);"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
</div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
<div class="van-image van-image-preview__image"><img src="https://img.yzcdn.cn/2.png" class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading">
<div class="van-loading van-loading--spinner"><span class="van-loading__spinner van-loading__spinner--spinner" style="color: rgb(201, 201, 201);"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
</div>
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
<div class="van-image van-image-preview__image"><img src="https://img.yzcdn.cn/3.png" class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading">
<div class="van-loading van-loading--spinner"><span class="van-loading__spinner van-loading__spinner--spinner" style="color: rgb(201, 201, 201);"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
</div>
</div>
</div>
<div class="van-image-preview__index">1/3</div>
</div>
`;
exports[`set show-index prop to false 1`] = `
<div class="van-image-preview" name="van-fade">
<div class="van-swipe">
<div class="van-swipe__track" style="width: 0px; transition-duration: 0ms; transform: translateX(0px);"></div>
</div>
</div>
`;
exports[`zoom 1`] = `
<div class="van-image-preview" name="van-fade">
<div class="van-swipe">
<div class="van-swipe__track" style="transition-duration: 500ms; width: 0px; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);"><img src="https://img.yzcdn.cn/1.png" class="van-image-preview__image" style="transform: scale3d(2, 2, 1) translate(0px, NaNpx);"></div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);"><img src="https://img.yzcdn.cn/2.png" class="van-image-preview__image"></div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);"><img src="https://img.yzcdn.cn/3.png" class="van-image-preview__image"></div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">
<div class="van-image van-image-preview__image" style="transform: scale3d(2, 2, 1) translate(0px, NaNpx);"><img src="https://img.yzcdn.cn/1.png" class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading">
<div class="van-loading van-loading--spinner"><span class="van-loading__spinner van-loading__spinner--spinner" style="color: rgb(201, 201, 201);"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">
<div class="van-image van-image-preview__image"><img src="https://img.yzcdn.cn/2.png" class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading">
<div class="van-loading van-loading--spinner"><span class="van-loading__spinner van-loading__spinner--spinner" style="color: rgb(201, 201, 201);"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
</div>
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">
<div class="van-image van-image-preview__image"><img src="https://img.yzcdn.cn/3.png" class="van-image__img" style="object-fit: contain;">
<div class="van-image__loading">
<div class="van-loading van-loading--spinner"><span class="van-loading__spinner van-loading__spinner--spinner" style="color: rgb(201, 201, 201);"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
</div>
</div>
</div>
<div class="van-image-preview__index">1/3</div>

View File

@ -136,6 +136,17 @@ test('zoom', async () => {
Element.prototype.getBoundingClientRect = getBoundingClientRect;
});
test('set show-index prop to false', () => {
const wrapper = mount(ImagePreviewVue, {
propsData: {
value: true,
showIndex: false
}
});
expect(wrapper).toMatchSnapshot();
});
test('index slot', () => {
const wrapper = mount({
template: `

View File

@ -1,37 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`click to preview image 1`] = `
<div
class="van-image-preview"
name="van-fade"
>
<div
class="van-swipe"
>
<div
class="van-swipe__track"
style="width: 0px; transition-duration: 0ms; transform: translateX(0px);"
>
<div
class="van-swipe-item"
style="width: 0px; height: 100%; transform: translateX(0px);"
>
<img
class="van-image-preview__image"
src="https://img.yzcdn.cn/vant/cat.jpeg"
style="transition: .3s all;"
/>
</div>
</div>
</div>
<div
class="van-image-preview__index"
>
1/1
</div>
</div>
`;
exports[`delete preview image 1`] = `
<div class="van-uploader">
<div class="van-uploader__wrapper">

View File

@ -341,7 +341,7 @@ it('click to preview image', () => {
wrapper.find('.van-image').trigger('click');
const imagePreviewNode2 = document.querySelector('.van-image-preview');
expect(imagePreviewNode2).toMatchSnapshot();
expect(imagePreviewNode2.querySelectorAll('.van-image-preview__image').length).toEqual(1);
});
it('click-preview event', () => {