mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[new feature] Image: add loading slot
This commit is contained in:
parent
1321ba6902
commit
d7b69d2fe4
@ -19,6 +19,7 @@
|
|||||||
>
|
>
|
||||||
<van-image
|
<van-image
|
||||||
:fit="fit"
|
:fit="fit"
|
||||||
|
width="100%"
|
||||||
height="27vw"
|
height="27vw"
|
||||||
:src="image"
|
:src="image"
|
||||||
/>
|
/>
|
||||||
@ -26,6 +27,33 @@
|
|||||||
</van-col>
|
</van-col>
|
||||||
</van-row>
|
</van-row>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block :title="$t('loading')">
|
||||||
|
<van-row gutter="20">
|
||||||
|
<van-col span="8">
|
||||||
|
<van-image
|
||||||
|
width="100%"
|
||||||
|
height="27vw"
|
||||||
|
/>
|
||||||
|
<div class="text">{{ $t('defaultTip') }}</div>
|
||||||
|
</van-col>
|
||||||
|
|
||||||
|
<van-col span="8">
|
||||||
|
<van-image
|
||||||
|
width="100%"
|
||||||
|
height="27vw"
|
||||||
|
>
|
||||||
|
<template v-slot:loading>
|
||||||
|
<van-loading
|
||||||
|
type="spinner"
|
||||||
|
size="20"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</van-image>
|
||||||
|
<div class="text">{{ $t('customTip') }}</div>
|
||||||
|
</van-col>
|
||||||
|
</van-row>
|
||||||
|
</demo-block>
|
||||||
</demo-section>
|
</demo-section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -33,10 +61,18 @@
|
|||||||
export default {
|
export default {
|
||||||
i18n: {
|
i18n: {
|
||||||
'zh-CN': {
|
'zh-CN': {
|
||||||
fitMode: '缩放模式'
|
fitMode: '填充模式',
|
||||||
|
loading: '加载中提示',
|
||||||
|
error: '加载失败提示',
|
||||||
|
defaultTip: '默认提示',
|
||||||
|
customTip: '自定义提示'
|
||||||
},
|
},
|
||||||
'en-US': {
|
'en-US': {
|
||||||
fitMode: 'Fit Mode'
|
fitMode: 'Fit Mode',
|
||||||
|
loading: 'Loading',
|
||||||
|
error: 'Error',
|
||||||
|
defaultTip: 'Default Tip',
|
||||||
|
customTip: 'Custom Tip'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -78,3 +78,9 @@ Vue.use(Lazyload);
|
|||||||
| click | Triggered when click image | event: Event |
|
| click | Triggered when click image | event: Event |
|
||||||
| load | Triggered when image loaded | - |
|
| load | Triggered when image loaded | - |
|
||||||
| error | Triggered when image load failed | - |
|
| error | Triggered when image load failed | - |
|
||||||
|
|
||||||
|
### Slots
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
|------|------|
|
||||||
|
| loading | Custom loading placeholder |
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { use, isDef, suffixPx } from '../utils';
|
import { use, isDef, suffixPx } from '../utils';
|
||||||
|
import Icon from '../icon';
|
||||||
|
|
||||||
const [sfc, bem] = use('image');
|
const [sfc, bem] = use('image');
|
||||||
|
|
||||||
@ -19,6 +20,13 @@ export default sfc({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
src() {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
style() {
|
style() {
|
||||||
const style = {};
|
const style = {};
|
||||||
@ -48,10 +56,19 @@ export default sfc({
|
|||||||
|
|
||||||
onClick(event) {
|
onClick(event) {
|
||||||
this.$emit('click', event);
|
this.$emit('click', event);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderContent() {
|
||||||
|
if (this.loading) {
|
||||||
|
return (
|
||||||
|
<div class={bem('loading')}>
|
||||||
|
{this.slots('loading') || <Icon name="photo-o" size="20" />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render(h) {
|
renderImage() {
|
||||||
const imgData = {
|
const imgData = {
|
||||||
class: bem('img'),
|
class: bem('img'),
|
||||||
attrs: {
|
attrs: {
|
||||||
@ -66,15 +83,19 @@ export default sfc({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Image = this.lazyLoad ? (
|
if (this.lazyLoad) {
|
||||||
<img vLazy={this.src} {...imgData} />
|
return <img vLazy={this.src} {...imgData} />;
|
||||||
) : (
|
}
|
||||||
<img src={this.src} {...imgData} />
|
|
||||||
);
|
|
||||||
|
|
||||||
|
return <img src={this.src} {...imgData} />;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render(h) {
|
||||||
return (
|
return (
|
||||||
<div class={bem()} style={this.style} onClick={this.onClick}>
|
<div class={bem()} style={this.style} onClick={this.onClick}>
|
||||||
{Image}
|
{this.renderImage()}
|
||||||
|
{this.renderContent()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,26 @@
|
|||||||
@import '../style/var';
|
@import '../style/var';
|
||||||
|
|
||||||
.van-image {
|
.van-image {
|
||||||
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
&__img {
|
&__img,
|
||||||
|
&__error,
|
||||||
|
&__loading {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__error,
|
||||||
|
&__loading {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: @gray-dark;
|
||||||
|
background-color: @background-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,32 +4,69 @@ exports[`renders demo correctly 1`] = `
|
|||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<div class="van-row">
|
<div class="van-row">
|
||||||
<div class="van-image" style="width: 100px; height: 100px;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img"></div>
|
<div class="van-image" style="width: 100px; height: 100px;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img">
|
||||||
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 20px;">
|
||||||
|
<!----></i></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="van-row" style="margin-left: -10px; margin-right: -10px;">
|
<div class="van-row" style="margin-left: -10px; margin-right: -10px;">
|
||||||
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
||||||
<div class="van-image" style="height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: contain;"></div>
|
<div class="van-image" style="width: 100%; height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: contain;">
|
||||||
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 20px;">
|
||||||
|
<!----></i></div>
|
||||||
|
</div>
|
||||||
<div class="text">contain</div>
|
<div class="text">contain</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
||||||
<div class="van-image" style="height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: cover;"></div>
|
<div class="van-image" style="width: 100%; height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: cover;">
|
||||||
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 20px;">
|
||||||
|
<!----></i></div>
|
||||||
|
</div>
|
||||||
<div class="text">cover</div>
|
<div class="text">cover</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
||||||
<div class="van-image" style="height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: fill;"></div>
|
<div class="van-image" style="width: 100%; height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: fill;">
|
||||||
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 20px;">
|
||||||
|
<!----></i></div>
|
||||||
|
</div>
|
||||||
<div class="text">fill</div>
|
<div class="text">fill</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
||||||
<div class="van-image" style="height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: none;"></div>
|
<div class="van-image" style="width: 100%; height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: none;">
|
||||||
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 20px;">
|
||||||
|
<!----></i></div>
|
||||||
|
</div>
|
||||||
<div class="text">none</div>
|
<div class="text">none</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
||||||
<div class="van-image" style="height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: scale-down;"></div>
|
<div class="van-image" style="width: 100%; height: 27vw;"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img" style="object-fit: scale-down;">
|
||||||
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 20px;">
|
||||||
|
<!----></i></div>
|
||||||
|
</div>
|
||||||
<div class="text">scale-down</div>
|
<div class="text">scale-down</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="van-row" style="margin-left: -10px; margin-right: -10px;">
|
||||||
|
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
||||||
|
<div class="van-image" style="width: 100%; height: 27vw;"><img class="van-image__img">
|
||||||
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 20px;">
|
||||||
|
<!----></i></div>
|
||||||
|
</div>
|
||||||
|
<div class="text">默认提示</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-col van-col--8" style="padding-left: 10px; padding-right: 10px;">
|
||||||
|
<div class="van-image" style="width: 100%; height: 27vw;"><img class="van-image__img">
|
||||||
|
<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); width: 20px; height: 20px;"><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 class="text">自定义提示</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`lazy load 1`] = `<div class="van-image"><img class="van-image__img"></div>`;
|
exports[`lazy load 1`] = `
|
||||||
|
<div class="van-image"><img class="van-image__img">
|
||||||
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 20px;">
|
||||||
|
<!----></i></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`load event 1`] = `<div class="van-image"><img src="https://img.yzcdn.cn/vant/cat.jpeg" class="van-image__img"></div>`;
|
||||||
|
|
||||||
|
exports[`load event 2`] = `
|
||||||
|
<div class="van-image"><img src="" class="van-image__img">
|
||||||
|
<div class="van-image__loading"><i class="van-icon van-icon-photo-o" style="font-size: 20px;">
|
||||||
|
<!----></i></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
@ -19,6 +19,10 @@ test('load event', () => {
|
|||||||
wrapper.find('img').trigger('load');
|
wrapper.find('img').trigger('load');
|
||||||
|
|
||||||
expect(wrapper.emitted('load')[0][0]).toBeTruthy();
|
expect(wrapper.emitted('load')[0][0]).toBeTruthy();
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
|
||||||
|
wrapper.setProps({ src: '' });
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('error event', () => {
|
test('error event', () => {
|
||||||
|
@ -20,7 +20,7 @@ Vue.use(Image);
|
|||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 缩放模式
|
### 填充模式
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<van-image
|
<van-image
|
||||||
@ -48,6 +48,18 @@ import { Lazyload } from 'vant';
|
|||||||
Vue.use(Lazyload);
|
Vue.use(Lazyload);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 加载中提示
|
||||||
|
|
||||||
|
`Image`组件默认提供了图片加载中的提示,可以通过插槽自定义加载中提示
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-image src="https://img.yzcdn.cn/vant/cat.jpeg">
|
||||||
|
<template v-slot:loading>
|
||||||
|
<van-loading type="spinner" size="20" />
|
||||||
|
</template>
|
||||||
|
</van-image>
|
||||||
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
### Props
|
### Props
|
||||||
@ -55,13 +67,13 @@ Vue.use(Lazyload);
|
|||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
|------|------|------|------|------|
|
|------|------|------|------|------|
|
||||||
| src | 图片链接 | `String` | - | - |
|
| src | 图片链接 | `String` | - | - |
|
||||||
| fit | 图片裁剪、缩放的模式 | `String` | `fill` | - |
|
| fit | 图片填充模式 | `String` | `fill` | - |
|
||||||
| alt | 替代文本 | `String` | - | - |
|
| alt | 替代文本 | `String` | - | - |
|
||||||
| width | 宽度,默认单位为 px | `String | Number` | - | - |
|
| width | 宽度,默认单位为 px | `String | Number` | - | - |
|
||||||
| height | 高度,默认单位为 px | `String | Number` | - | - |
|
| height | 高度,默认单位为 px | `String | Number` | - | - |
|
||||||
| lazy-load | 是否开启图片懒加载,须配合 [Lazyload](#/zh-CN/lazyload) 组件使用 | `Boolean` | `false` | - |
|
| lazy-load | 是否开启图片懒加载,须配合 [Lazyload](#/zh-CN/lazyload) 组件使用 | `Boolean` | `false` | - |
|
||||||
|
|
||||||
### fit 可选值
|
### 图片填充模式
|
||||||
|
|
||||||
| 名称 | 含义 |
|
| 名称 | 含义 |
|
||||||
|------|------|
|
|------|------|
|
||||||
@ -78,3 +90,9 @@ Vue.use(Lazyload);
|
|||||||
| click | 点击图片时触发 | event: Event |
|
| click | 点击图片时触发 | event: Event |
|
||||||
| load | 图片加载完毕时触发 | - |
|
| load | 图片加载完毕时触发 | - |
|
||||||
| error | 图片加载失败时触发 | - |
|
| error | 图片加载失败时触发 | - |
|
||||||
|
|
||||||
|
### Slots
|
||||||
|
|
||||||
|
| 名称 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| loading | 自定义加载状态显示内容 |
|
||||||
|
Loading…
x
Reference in New Issue
Block a user