refactor(Image-Preview): Refactor placeholder from vNode type to () => vNode

pull/8322/head
shuoxian 2025-09-01 20:11:35 +08:00
parent ea5e27224f
commit 0845fad612
5 changed files with 29 additions and 23 deletions

View File

@ -18,18 +18,18 @@ You can set different preview image. You can also customize the loading placehol
<template>
<a-image
:width="200"
src="https://aliyuncdn.antdv.com/logo.png"
:width="200"
:preview="{
src: 'http://47.100.102.7:11501/admin-api/infra/file/24/get//algorithm/execute/2025/08/20/20210628_iPhoneSE_YL_42_1755674307938_1755674703040.jpg',
placeholder: h(CustomLoadingComp),
src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
placeholder: () => CustomLoadingComp,
}"
/>
<a-image
:width="200"
src="https://aliyuncdn.antdv.com/logo.png"
:preview="{
src: 'http://47.100.102.7:11501/admin-api/infra/file/24/get//algorithm/execute/2025/08/20/20210628_iPhoneSE_YL_42_1755674307938_1755674703040.jpg',
src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
placeholder: true,
}"
/>

View File

@ -38,11 +38,12 @@ Previewable image.
{
visible?: boolean;
onVisibleChange?: (visible, prevVisible) => void;
getContainer?: string | HTMLElement | (() => HTMLElement);
getContainer: string | HTMLElement | (() => HTMLElement);
src?: string;
maskClassName?: string;
current?: number;
placeholder?: (() => vNode) | boolean;
}
```
Other attributes [&lt;img>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Attributes)
Other attributes [&lt;img&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Attributes)

View File

@ -43,8 +43,8 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LVQ3R5JjjJEAAA
src?: string;
maskClassName?: string;
current?: number;
placeholder?: VNode | boolean;
placeholder?: (() => vNode) | boolean;
}
```
其他属性见 [&lt;img>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Attributes)
其他属性见 [&lt;img&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Attributes)

View File

@ -20,7 +20,7 @@ export type ImagePreviewType = Omit<
src?: string;
visible?: boolean;
fallback?: string;
placeholder?: VNode | boolean;
placeholder?: boolean | (() => VNode);
onVisibleChange?: (value: boolean, prevValue: boolean) => void;
getContainer?: GetContainer | false;
maskClassName?: string;

View File

@ -8,7 +8,6 @@ import {
watch,
cloneVNode,
ref,
isVNode,
nextTick,
} from 'vue';
import type { VNode, Ref, PropType } from 'vue';
@ -32,6 +31,7 @@ export interface PreviewProps extends Omit<IDialogChildProps, 'onClose' | 'mask'
src?: string;
alt?: string;
rootClassName?: string;
placeholder?: boolean | (() => VNode);
icons?: {
rotateLeft?: VNode;
rotateRight?: VNode;
@ -55,7 +55,7 @@ export const previewProps = {
alt: String,
fallback: String,
placeholder: {
type: Object as PropType<VNode | boolean>,
type: [Boolean, Function] as PropType<boolean | (() => VNode)>,
default: () => true,
},
rootClassName: String,
@ -75,7 +75,8 @@ const Preview = defineComponent({
props.icons,
);
// placeholder
const isCustomPlaceholder = computed(() => isVNode(props.placeholder));
const isCustomPlaceholder = computed(() => typeof props.placeholder === 'function');
const isDefaultPlaceholder = computed(() => {
return props.placeholder === true;
});
@ -88,6 +89,10 @@ const Preview = defineComponent({
status.value = 'loading';
},
);
const renderPlaceholder = () => {
const { placeholder } = props;
return typeof placeholder === 'function' ? placeholder() : placeholder;
};
const scale = shallowRef(1);
const rotate = shallowRef(0);
const flip = reactive({ x: 1, y: 1 });
@ -427,7 +432,7 @@ const Preview = defineComponent({
<Spin size="large" class={`${props.prefixCls}-img-placeholder`}></Spin>
)}
{isCustomPlaceholder.value && status.value === 'loading' && (
<div class={`${props.prefixCls}-img-placeholder`}>{props.placeholder}</div>
<div class={`${props.prefixCls}-img-placeholder`}>{renderPlaceholder()}</div>
)}
</div>
{showLeftOrRightSwitches.value && (