mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(ImagePreview): add image loading tip (#4378)
This commit is contained in:
parent
b9c1dca67c
commit
3f8ffccb36
@ -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>
|
||||
);
|
||||
|
@ -94,6 +94,7 @@ export default {
|
||||
showImagePreview(position, timer) {
|
||||
const instance = ImagePreview({
|
||||
images,
|
||||
lazyLoad: true,
|
||||
swipeDuration: 300,
|
||||
asyncClose: !!timer,
|
||||
closeOnPopstate: true,
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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: `
|
||||
|
@ -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">
|
||||
|
@ -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', () => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user