Skip to content

Commit 3f8ffcc

Browse files
authored
feat(ImagePreview): add image loading tip (youzan#4378)
1 parent b9c1dca commit 3f8ffcc

7 files changed

Lines changed: 138 additions & 94 deletions

File tree

src/image-preview/ImagePreview.js

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { preventDefault } from '../utils/dom/event';
44
import { PopupMixin } from '../mixins/popup';
55
import { TouchMixin } from '../mixins/touch';
66
import { CloseOnPopstateMixin } from '../mixins/close-on-popstate';
7+
import Image from '../image';
8+
import Loading from '../loading';
79
import Swipe from '../swipe';
810
import SwipeItem from '../swipe-item';
911

@@ -19,11 +21,7 @@ function getDistance(touches) {
1921
}
2022

2123
export default createComponent({
22-
mixins: [
23-
PopupMixin,
24-
TouchMixin,
25-
CloseOnPopstateMixin
26-
],
24+
mixins: [PopupMixin, TouchMixin, CloseOnPopstateMixin],
2725

2826
props: {
2927
className: null,
@@ -253,6 +251,51 @@ export default createComponent({
253251
this.scale = scale;
254252
this.moveX = 0;
255253
this.moveY = 0;
254+
},
255+
256+
genIndex() {
257+
if (this.showIndex) {
258+
return (
259+
<div class={bem('index')}>
260+
{this.slots('index') || `${this.active + 1}/${this.images.length}`}
261+
</div>
262+
);
263+
}
264+
},
265+
266+
genImages() {
267+
const imageSlots = {
268+
loading: () => <Loading type="spinner" />
269+
};
270+
271+
return (
272+
<Swipe
273+
ref="swipe"
274+
loop={this.loop}
275+
duration={this.swipeDuration}
276+
indicatorColor="white"
277+
initialSwipe={this.startPosition}
278+
showIndicators={this.showIndicators}
279+
onChange={this.setActive}
280+
>
281+
{this.images.map((image, index) => (
282+
<SwipeItem>
283+
<Image
284+
src={image}
285+
fit="contain"
286+
class={bem('image')}
287+
lazyLoad={this.lazyLoad}
288+
scopedSlots={imageSlots}
289+
style={index === this.active ? this.imageStyle : null}
290+
nativeOnTouchstart={this.onImageTouchStart}
291+
nativeOnTouchmove={this.onImageTouchMove}
292+
nativeOnTouchend={this.onImageTouchEnd}
293+
nativeOnTouchcancel={this.onImageTouchEnd}
294+
/>
295+
</SwipeItem>
296+
))}
297+
</Swipe>
298+
);
256299
}
257300
},
258301

@@ -261,48 +304,6 @@ export default createComponent({
261304
return;
262305
}
263306

264-
const { active, images } = this;
265-
266-
const Index = this.showIndex && (
267-
<div class={bem('index')}>
268-
{this.slots('index') || `${active + 1}/${images.length}`}
269-
</div>
270-
);
271-
272-
const Images = (
273-
<Swipe
274-
ref="swipe"
275-
loop={this.loop}
276-
duration={this.swipeDuration}
277-
indicatorColor="white"
278-
initialSwipe={this.startPosition}
279-
showIndicators={this.showIndicators}
280-
onChange={this.setActive}
281-
>
282-
{images.map((image, index) => {
283-
const props = {
284-
class: bem('image'),
285-
style: index === active ? this.imageStyle : null,
286-
on: {
287-
touchstart: this.onImageTouchStart,
288-
touchmove: this.onImageTouchMove,
289-
touchend: this.onImageTouchEnd,
290-
touchcancel: this.onImageTouchEnd
291-
}
292-
};
293-
return (
294-
<SwipeItem>
295-
{this.lazyLoad ? (
296-
<img vLazy={image} {...props} />
297-
) : (
298-
<img src={image} {...props} />
299-
)}
300-
</SwipeItem>
301-
);
302-
})}
303-
</Swipe>
304-
);
305-
306307
return (
307308
<transition name="van-fade">
308309
<div
@@ -312,8 +313,8 @@ export default createComponent({
312313
onTouchend={this.onWrapperTouchEnd}
313314
onTouchcancel={this.onWrapperTouchEnd}
314315
>
315-
{Images}
316-
{Index}
316+
{this.genImages()}
317+
{this.genIndex()}
317318
</div>
318319
</transition>
319320
);

src/image-preview/demo/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export default {
9494
showImagePreview(position, timer) {
9595
const instance = ImagePreview({
9696
images,
97+
lazyLoad: true,
9798
swipeDuration: 300,
9899
asyncClose: !!timer,
99100
closeOnPopstate: true,

src/image-preview/index.less

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313
right: 0;
1414
bottom: 0;
1515
left: 0;
16-
max-width: 100%;
17-
max-height: 100%;
18-
margin: auto;
16+
17+
.van-image__loading {
18+
background-color: transparent;
19+
}
1920
}
2021

2122
&__index {

src/image-preview/test/__snapshots__/index.spec.js.snap

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,27 @@ exports[`lazy-load prop 1`] = `
1313
<div class="van-image-preview" name="van-fade">
1414
<div class="van-swipe">
1515
<div class="van-swipe__track" style="width: 0px; transition-duration: 0ms; transform: translateX(0px);">
16-
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img class="van-image-preview__image" style="transition: .3s all;"></div>
17-
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img class="van-image-preview__image"></div>
18-
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img class="van-image-preview__image"></div>
16+
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
17+
<div class="van-image van-image-preview__image" style="transition: .3s all;"><img class="van-image__img" style="object-fit: contain;">
18+
<div class="van-image__loading">
19+
<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>
20+
</div>
21+
</div>
22+
</div>
23+
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
24+
<div class="van-image van-image-preview__image"><img class="van-image__img" style="object-fit: contain;">
25+
<div class="van-image__loading">
26+
<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>
27+
</div>
28+
</div>
29+
</div>
30+
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
31+
<div class="van-image van-image-preview__image"><img class="van-image__img" style="object-fit: contain;">
32+
<div class="van-image__loading">
33+
<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>
34+
</div>
35+
</div>
36+
</div>
1937
</div>
2038
</div>
2139
<div class="van-image-preview__index">1/3</div>
@@ -26,22 +44,66 @@ exports[`render image 1`] = `
2644
<div class="van-image-preview" name="van-fade">
2745
<div class="van-swipe">
2846
<div class="van-swipe__track" style="width: 0px; transition-duration: 500ms; transform: translateX(0px);">
29-
<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>
30-
<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>
31-
<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>
47+
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
48+
<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;">
49+
<div class="van-image__loading">
50+
<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>
51+
</div>
52+
</div>
53+
</div>
54+
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
55+
<div class="van-image van-image-preview__image"><img src="https://img.yzcdn.cn/2.png" class="van-image__img" style="object-fit: contain;">
56+
<div class="van-image__loading">
57+
<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>
58+
</div>
59+
</div>
60+
</div>
61+
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);">
62+
<div class="van-image van-image-preview__image"><img src="https://img.yzcdn.cn/3.png" class="van-image__img" style="object-fit: contain;">
63+
<div class="van-image__loading">
64+
<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>
65+
</div>
66+
</div>
67+
</div>
3268
</div>
3369
</div>
3470
<div class="van-image-preview__index">1/3</div>
3571
</div>
3672
`;
3773
74+
exports[`set show-index prop to false 1`] = `
75+
<div class="van-image-preview" name="van-fade">
76+
<div class="van-swipe">
77+
<div class="van-swipe__track" style="width: 0px; transition-duration: 0ms; transform: translateX(0px);"></div>
78+
</div>
79+
</div>
80+
`;
81+
3882
exports[`zoom 1`] = `
3983
<div class="van-image-preview" name="van-fade">
4084
<div class="van-swipe">
4185
<div class="van-swipe__track" style="transition-duration: 500ms; width: 0px; transform: translateX(0px);">
42-
<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>
43-
<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>
44-
<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>
86+
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">
87+
<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;">
88+
<div class="van-image__loading">
89+
<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>
90+
</div>
91+
</div>
92+
</div>
93+
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">
94+
<div class="van-image van-image-preview__image"><img src="https://img.yzcdn.cn/2.png" class="van-image__img" style="object-fit: contain;">
95+
<div class="van-image__loading">
96+
<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>
97+
</div>
98+
</div>
99+
</div>
100+
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);">
101+
<div class="van-image van-image-preview__image"><img src="https://img.yzcdn.cn/3.png" class="van-image__img" style="object-fit: contain;">
102+
<div class="van-image__loading">
103+
<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>
104+
</div>
105+
</div>
106+
</div>
45107
</div>
46108
</div>
47109
<div class="van-image-preview__index">1/3</div>

src/image-preview/test/index.spec.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,17 @@ test('zoom', async () => {
136136
Element.prototype.getBoundingClientRect = getBoundingClientRect;
137137
});
138138

139+
test('set show-index prop to false', () => {
140+
const wrapper = mount(ImagePreviewVue, {
141+
propsData: {
142+
value: true,
143+
showIndex: false
144+
}
145+
});
146+
147+
expect(wrapper).toMatchSnapshot();
148+
});
149+
139150
test('index slot', () => {
140151
const wrapper = mount({
141152
template: `

src/uploader/test/__snapshots__/index.spec.js.snap

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,5 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`click to preview image 1`] = `
4-
<div
5-
class="van-image-preview"
6-
name="van-fade"
7-
>
8-
<div
9-
class="van-swipe"
10-
>
11-
<div
12-
class="van-swipe__track"
13-
style="width: 0px; transition-duration: 0ms; transform: translateX(0px);"
14-
>
15-
<div
16-
class="van-swipe-item"
17-
style="width: 0px; height: 100%; transform: translateX(0px);"
18-
>
19-
<img
20-
class="van-image-preview__image"
21-
src="https://img.yzcdn.cn/vant/cat.jpeg"
22-
style="transition: .3s all;"
23-
/>
24-
</div>
25-
</div>
26-
</div>
27-
<div
28-
class="van-image-preview__index"
29-
>
30-
1/1
31-
</div>
32-
</div>
33-
`;
34-
353
exports[`delete preview image 1`] = `
364
<div class="van-uploader">
375
<div class="van-uploader__wrapper">

src/uploader/test/index.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ it('click to preview image', () => {
341341
wrapper.find('.van-image').trigger('click');
342342

343343
const imagePreviewNode2 = document.querySelector('.van-image-preview');
344-
expect(imagePreviewNode2).toMatchSnapshot();
344+
expect(imagePreviewNode2.querySelectorAll('.van-image-preview__image').length).toEqual(1);
345345
});
346346

347347
it('click-preview event', () => {

0 commit comments

Comments
 (0)