mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-25 10:56:35 +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 { PopupMixin } from '../mixins/popup';
|
||||||
import { TouchMixin } from '../mixins/touch';
|
import { TouchMixin } from '../mixins/touch';
|
||||||
import { CloseOnPopstateMixin } from '../mixins/close-on-popstate';
|
import { CloseOnPopstateMixin } from '../mixins/close-on-popstate';
|
||||||
|
import Image from '../image';
|
||||||
|
import Loading from '../loading';
|
||||||
import Swipe from '../swipe';
|
import Swipe from '../swipe';
|
||||||
import SwipeItem from '../swipe-item';
|
import SwipeItem from '../swipe-item';
|
||||||
|
|
||||||
@ -19,11 +21,7 @@ function getDistance(touches) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
mixins: [
|
mixins: [PopupMixin, TouchMixin, CloseOnPopstateMixin],
|
||||||
PopupMixin,
|
|
||||||
TouchMixin,
|
|
||||||
CloseOnPopstateMixin
|
|
||||||
],
|
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
className: null,
|
className: null,
|
||||||
@ -253,23 +251,24 @@ export default createComponent({
|
|||||||
this.scale = scale;
|
this.scale = scale;
|
||||||
this.moveX = 0;
|
this.moveX = 0;
|
||||||
this.moveY = 0;
|
this.moveY = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
genIndex() {
|
||||||
|
if (this.showIndex) {
|
||||||
|
return (
|
||||||
|
<div class={bem('index')}>
|
||||||
|
{this.slots('index') || `${this.active + 1}/${this.images.length}`}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
genImages() {
|
||||||
if (!this.value) {
|
const imageSlots = {
|
||||||
return;
|
loading: () => <Loading type="spinner" />
|
||||||
}
|
};
|
||||||
|
|
||||||
const { active, images } = this;
|
return (
|
||||||
|
|
||||||
const Index = this.showIndex && (
|
|
||||||
<div class={bem('index')}>
|
|
||||||
{this.slots('index') || `${active + 1}/${images.length}`}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const Images = (
|
|
||||||
<Swipe
|
<Swipe
|
||||||
ref="swipe"
|
ref="swipe"
|
||||||
loop={this.loop}
|
loop={this.loop}
|
||||||
@ -279,29 +278,31 @@ export default createComponent({
|
|||||||
showIndicators={this.showIndicators}
|
showIndicators={this.showIndicators}
|
||||||
onChange={this.setActive}
|
onChange={this.setActive}
|
||||||
>
|
>
|
||||||
{images.map((image, index) => {
|
{this.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>
|
<SwipeItem>
|
||||||
{this.lazyLoad ? (
|
<Image
|
||||||
<img vLazy={image} {...props} />
|
src={image}
|
||||||
) : (
|
fit="contain"
|
||||||
<img src={image} {...props} />
|
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>
|
</SwipeItem>
|
||||||
);
|
))}
|
||||||
})}
|
|
||||||
</Swipe>
|
</Swipe>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (!this.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<transition name="van-fade">
|
<transition name="van-fade">
|
||||||
@ -312,8 +313,8 @@ export default createComponent({
|
|||||||
onTouchend={this.onWrapperTouchEnd}
|
onTouchend={this.onWrapperTouchEnd}
|
||||||
onTouchcancel={this.onWrapperTouchEnd}
|
onTouchcancel={this.onWrapperTouchEnd}
|
||||||
>
|
>
|
||||||
{Images}
|
{this.genImages()}
|
||||||
{Index}
|
{this.genIndex()}
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
);
|
);
|
||||||
|
@ -94,6 +94,7 @@ export default {
|
|||||||
showImagePreview(position, timer) {
|
showImagePreview(position, timer) {
|
||||||
const instance = ImagePreview({
|
const instance = ImagePreview({
|
||||||
images,
|
images,
|
||||||
|
lazyLoad: true,
|
||||||
swipeDuration: 300,
|
swipeDuration: 300,
|
||||||
asyncClose: !!timer,
|
asyncClose: !!timer,
|
||||||
closeOnPopstate: true,
|
closeOnPopstate: true,
|
||||||
|
@ -13,9 +13,10 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
.van-image__loading {
|
||||||
margin: auto;
|
background-color: transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__index {
|
&__index {
|
||||||
|
@ -13,9 +13,27 @@ exports[`lazy-load prop 1`] = `
|
|||||||
<div class="van-image-preview" name="van-fade">
|
<div class="van-image-preview" name="van-fade">
|
||||||
<div class="van-swipe">
|
<div class="van-swipe">
|
||||||
<div class="van-swipe__track" style="width: 0px; transition-duration: 0ms; transform: translateX(0px);">
|
<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);">
|
||||||
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img class="van-image-preview__image"></div>
|
<div class="van-image van-image-preview__image" style="transition: .3s all;"><img class="van-image__img" style="object-fit: contain;">
|
||||||
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img class="van-image-preview__image"></div>
|
<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>
|
</div>
|
||||||
<div class="van-image-preview__index">1/3</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-image-preview" name="van-fade">
|
||||||
<div class="van-swipe">
|
<div class="van-swipe">
|
||||||
<div class="van-swipe__track" style="width: 0px; transition-duration: 500ms; transform: translateX(0px);">
|
<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);">
|
||||||
<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-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-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-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>
|
</div>
|
||||||
<div class="van-image-preview__index">1/3</div>
|
<div class="van-image-preview__index">1/3</div>
|
||||||
</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`] = `
|
exports[`zoom 1`] = `
|
||||||
<div class="van-image-preview" name="van-fade">
|
<div class="van-image-preview" name="van-fade">
|
||||||
<div class="van-swipe">
|
<div class="van-swipe">
|
||||||
<div class="van-swipe__track" style="transition-duration: 500ms; width: 0px; transform: translateX(0px);">
|
<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);">
|
||||||
<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-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-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-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>
|
</div>
|
||||||
<div class="van-image-preview__index">1/3</div>
|
<div class="van-image-preview__index">1/3</div>
|
||||||
|
@ -136,6 +136,17 @@ test('zoom', async () => {
|
|||||||
Element.prototype.getBoundingClientRect = getBoundingClientRect;
|
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', () => {
|
test('index slot', () => {
|
||||||
const wrapper = mount({
|
const wrapper = mount({
|
||||||
template: `
|
template: `
|
||||||
|
@ -1,37 +1,5 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// 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`] = `
|
exports[`delete preview image 1`] = `
|
||||||
<div class="van-uploader">
|
<div class="van-uploader">
|
||||||
<div class="van-uploader__wrapper">
|
<div class="van-uploader__wrapper">
|
||||||
|
@ -341,7 +341,7 @@ it('click to preview image', () => {
|
|||||||
wrapper.find('.van-image').trigger('click');
|
wrapper.find('.van-image').trigger('click');
|
||||||
|
|
||||||
const imagePreviewNode2 = document.querySelector('.van-image-preview');
|
const imagePreviewNode2 = document.querySelector('.van-image-preview');
|
||||||
expect(imagePreviewNode2).toMatchSnapshot();
|
expect(imagePreviewNode2.querySelectorAll('.van-image-preview__image').length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('click-preview event', () => {
|
it('click-preview event', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user