Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ImagePreview): add preview image slot #11133

Merged
merged 1 commit into from
Oct 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/vant/src/image-preview/ImagePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ export default defineComponent({
rootHeight={state.rootHeight}
onScale={emitScale}
onClose={emitClose}
v-slots={{
image: slots.image,
}}
/>
))}
</Swipe>
Expand Down
24 changes: 15 additions & 9 deletions packages/vant/src/image-preview/ImagePreviewItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default defineComponent({

emits: ['scale', 'close'],

setup(props, { emit }) {
setup(props, { emit, slots }) {
const state = reactive({
scale: 1,
moveX: 0,
Expand Down Expand Up @@ -293,14 +293,20 @@ export default defineComponent({
onTouchend={onTouchEnd}
onTouchcancel={onTouchEnd}
>
<Image
v-slots={imageSlots}
src={props.src}
fit="contain"
class={bem('image', { vertical: vertical.value })}
style={imageStyle.value}
onLoad={onLoad}
/>
{slots.image ? (
<div class={bem('image-wrap')}>
{slots.image({ src: props.src })}
</div>
) : (
<Image
v-slots={imageSlots}
src={props.src}
fit="contain"
class={bem('image', { vertical: vertical.value })}
style={imageStyle.value}
onLoad={onLoad}
/>
)}
</SwipeItem>
);
};
Expand Down
37 changes: 37 additions & 0 deletions packages/vant/src/image-preview/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,42 @@ export default {
};
```

### Component Call use image slot

```html
<van-image-preview v-model:show="show" :images="images" @change="onChange">
<template #image="{src}">
<video style="width: 100%;" controls><source :src="src" /></video>
</template>
</van-image-preview>
```

```js
import { ref } from 'vue';

export default {
setup() {
const show = ref(false);
const index = ref(0);
const images = [
'https://www.w3school.com.cn/i/movie.ogg',
'https://www.w3school.com.cn/i/movie.ogg',
'https://www.w3school.com.cn/i/movie.ogg',
];
const onChange = (newIndex) => {
index.value = newIndex;
};

return {
show,
index,
images,
onChange,
};
},
};
```

## API

### Options
Expand Down Expand Up @@ -218,6 +254,7 @@ imagePreviewRef.value?.swipeTo(1);
| --- | --- | --- |
| index | Custom index | { index: index of current image } |
| cover | Custom content that covers the image preview | - |
| image | Custom image slot | { src: current image src } |

### onClose Parameters

Expand Down
37 changes: 37 additions & 0 deletions packages/vant/src/image-preview/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,42 @@ export default {
};
```

### 组件调用 - 使用 image 插槽

```html
<van-image-preview v-model:show="show" :images="images" @change="onChange">
<template #image="{src}">
<video style="width: 100%;" controls><source :src="src" /></video>
</template>
</van-image-preview>
```

```js
import { ref } from 'vue';

export default {
setup() {
const show = ref(false);
const index = ref(0);
const images = [
'https://www.w3school.com.cn/i/movie.ogg',
'https://www.w3school.com.cn/i/movie.ogg',
'https://www.w3school.com.cn/i/movie.ogg',
];
const onChange = (newIndex) => {
index.value = newIndex;
};

return {
show,
index,
images,
onChange,
};
},
};
```

## API

### Options
Expand Down Expand Up @@ -279,6 +315,7 @@ imagePreviewRef.value?.swipeTo(1);
| ----- | ------------------------------ | ------------------------- |
| index | 自定义页码内容 | { index: 当前图片的索引 } |
| cover | 自定义覆盖在图片预览上方的内容 | - |
| image | 自定义图片插槽 | { src: 当前资源地址 } |

### onClose 回调参数

Expand Down
37 changes: 37 additions & 0 deletions packages/vant/src/image-preview/demo/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const t = useTranslate({
customConfig: '传入配置项',
startPosition: '指定初始位置',
componentCall: '组件调用',
componentImage: '组件调用使用image插槽',
index: (index: number) => `第${index + 1}页`,
},
'en-US': {
Expand All @@ -28,6 +29,7 @@ const t = useTranslate({
customConfig: 'Custom Config',
startPosition: 'Set Start Position',
componentCall: 'Component Call',
componentImage: 'Component Call use image slot',
index: (index: number) => `Page: ${index}`,
},
});
Expand All @@ -39,9 +41,19 @@ const images = [
cdnURL('apple-4.jpeg'),
];

const imagesSlot = [
'https://www.w3school.com.cn/i/movie.ogg',
'https://www.w3school.com.cn/i/movie.ogg',
'https://www.w3school.com.cn/i/movie.ogg',
'https://www.w3school.com.cn/i/movie.ogg',
];

const show = ref(false);
const index = ref(0);

const showSlot = ref(false);
const indexSlot = ref(0);

const onClose = () => Toast(t('closed'));

const beforeClose = () =>
Expand All @@ -59,6 +71,14 @@ const onChange = (newIndex: number) => {
index.value = newIndex;
};

const showComponentCallSlot = () => {
showSlot.value = true;
};

const onChangeSlot = (newIndex: number) => {
indexSlot.value = newIndex;
};

const showImagePreview = (options: Partial<ImagePreviewOptions> = {}) => {
const instance = ImagePreview({
images,
Expand Down Expand Up @@ -110,4 +130,21 @@ const showImagePreview = (options: Partial<ImagePreviewOptions> = {}) => {
<template #index>{{ t('index', index) }}</template>
</van-image-preview>
</demo-block>

<demo-block card :title="t('componentImage')">
<van-cell
is-link
:value="t('componentImage')"
@click="showComponentCallSlot"
/>
<van-image-preview
v-model:show="showSlot"
:images="imagesSlot"
@change="onChangeSlot"
>
<template #image="{ src }">
<video style="width: 100%" controls><source :src="src" /></video>
</template>
</van-image-preview>
</demo-block>
</template>
6 changes: 4 additions & 2 deletions packages/vant/src/image-preview/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
left: 0;
}

&__image {
&__image,
&__image-wrap {
width: 100%;
transition-property: transform;

Expand All @@ -47,7 +48,8 @@
height: 100%;
}

img {
img,
video {
// disable desktop browser image drag
-webkit-user-drag: none;
}
Expand Down
33 changes: 33 additions & 0 deletions packages/vant/src/image-preview/test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,36 @@ test('zoom out', async () => {

restore();
});

test('should render image slot correctly', async () => {
const wrapper = mount(ImagePreviewComponent, {
props: {
show: true,
images,
},
slots: {
image: ({ src }) => `<img class="test-img" src="${src}" />`,
},
});

await later();

expect(wrapper.html().includes('test-img')).toBeTruthy();
});

test('should render image slot correctly 2', async () => {
const wrapper = mount(ImagePreviewComponent, {
props: {
show: true,
images,
},
slots: {
image: ({ src }) =>
`<video style="width: 100%;" controls><source src="${src}" /></video>`,
},
});

await later();

expect(wrapper.html().includes('video')).toBeTruthy();
});