Skip to content

Commit ed37554

Browse files
authored
feat(image): support fallback and referrerpolicy (#1647)
* feat(image): support referrerpolicy * feat(image): support fallback * test: add fallback test case
1 parent 687226b commit ed37554

File tree

6 files changed

+72
-14
lines changed

6 files changed

+72
-14
lines changed

src/image/__test__/index.test.jsx

+10
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ describe('Image', () => {
114114
expect(onError).toBeCalledTimes(0);
115115
});
116116

117+
it(': fallback', async () => {
118+
const onError = vi.fn();
119+
const wrapper = mount(() => <Image src={FAIL_IMAGE} fallback={IMAGE} onError={onError} />);
120+
await nextTick();
121+
const $image = wrapper.find(`.${name}__img`);
122+
// 手动触发 图片加载失败的回调函数
123+
await $image.trigger('error');
124+
expect($image.attributes('src')).toBe(IMAGE);
125+
});
126+
117127
it(': onError', async () => {
118128
const onError = vi.fn();
119129
const slots = {

src/image/image.en-US.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ name | type | default | description | required
88
-- | -- | -- | -- | --
99
alt | String | - | \- | N
1010
error | String / Slot / Function | - | Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
11-
fit | String | fill | options:contain/cover/fill/none/scale-down | N
11+
fallback | String | - | display `fallback` image on `src` loading failed. you can also use `error` to define more complex error content | N
12+
fit | String | fill | options: contain/cover/fill/none/scale-down | N
1213
lazy | Boolean | false | \- | N
1314
loading | String / Slot / Function | - | Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
1415
position | String | center | \- | N
15-
shape | String | square | options:circle/round/square | N
16+
referrerpolicy | String | - | attribute of `<img>`, [MDN Definition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy)。options: no-referrer/no-referrer-when-downgrade/origin/origin-when-cross-origin/same-origin/strict-origin/strict-origin-when-cross-origin/unsafe-url | N
17+
shape | String | square | options: circle/round/square | N
1618
src | String | - | \- | N
17-
srcset | Object | - | for `.avif` and `.webp` image url。Typescript:`ImageSrcset` `interface ImageSrcset { 'image/avif': string; 'image/webp': string; }`[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/image/type.ts) | N
19+
srcset | Object | - | for `.avif` and `.webp` image url, load `srcset` before `src`。Typescript:`ImageSrcset` `interface ImageSrcset { 'image/avif': string; 'image/webp': string; }`[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/image/type.ts) | N
1820
onError | Function | | Typescript:`(context: { e: ImageEvent }) => void`<br/>trigger on image load failed | N
1921
onLoad | Function | | Typescript:`(context: { e: ImageEvent }) => void`<br/>trigger on image loaded | N
2022

@@ -25,12 +27,12 @@ name | params | description
2527
error | `(context: { e: ImageEvent })` | trigger on image load failed
2628
load | `(context: { e: ImageEvent })` | trigger on image loaded
2729

28-
2930
### CSS Variables
31+
3032
The component provides the following CSS variables, which can be used to customize styles.
3133
Name | Default Value | Description
3234
-- | -- | --
3335
--td-image-color | @font-gray-3 | -
3436
--td-image-loading-bg-color | @bg-color-secondarycontainer | -
3537
--td-image-loading-color | @font-gray-3 | -
36-
--td-image-round-radius | @radius-default | -
38+
--td-image-round-radius | @radius-default | -

src/image/image.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
:: BASE_DOC ::
22

33
## API
4+
45
### Image Props
56

6-
名称 | 类型 | 默认值 | 说明 | 必传
7+
名称 | 类型 | 默认值 | 描述 | 必传
78
-- | -- | -- | -- | --
89
alt | String | - | 图片描述 | N
910
error | String / Slot / Function | - | 自定义图片加载失败状态下的显示内容。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
11+
fallback | String | - | 图片加载失败时,显示当前链接设置的图片地址。如果要使用组件图标或完全自定义加载失败时显示的内容,请更为使用 `error` | N
1012
fit | String | fill | 图片填充模式。可选项:contain/cover/fill/none/scale-down | N
1113
lazy | Boolean | false | 是否开启图片懒加载 | N
1214
loading | String / Slot / Function | - | 自定义加载中状态的图片内容,如:“加载中”。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
1315
position | String | center | 等同于原生的 object-position 属性,可选值为 top right bottom left 或 string,可以自定义任何单位,px 或者 百分比 | N
16+
referrerpolicy | String | - | `<img>` 标签的原生属性,[MDN 定义](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy)。可选项:no-referrer/no-referrer-when-downgrade/origin/origin-when-cross-origin/same-origin/strict-origin/strict-origin-when-cross-origin/unsafe-url | N
1417
shape | String | square | 图片圆角类型。可选项:circle/round/square | N
1518
src | String | - | 图片链接 | N
16-
srcset | Object | - | 图片地址,支持特殊格式的图片,如 `.avif``.webp`。TS 类型:`ImageSrcset` `interface ImageSrcset { 'image/avif': string; 'image/webp': string; }`[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/image/type.ts) | N
19+
srcset | Object | - | 图片链接集合,用于支持特殊格式的图片,如 `.avif``.webp`。会优先加载 `srcset` 中的图片格式,浏览器不支持的情况下,加载 `src` 设置的图片地址。TS 类型:`ImageSrcset` `interface ImageSrcset { 'image/avif': string; 'image/webp': string; }`[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/image/type.ts) | N
1720
onError | Function | | TS 类型:`(context: { e: ImageEvent }) => void`<br/>图片加载失败时触发 | N
1821
onLoad | Function | | TS 类型:`(context: { e: ImageEvent }) => void`<br/>图片加载完成时触发 | N
1922

@@ -24,12 +27,12 @@ onLoad | Function | | TS 类型:`(context: { e: ImageEvent }) => void`<br/>
2427
error | `(context: { e: ImageEvent })` | 图片加载失败时触发
2528
load | `(context: { e: ImageEvent })` | 图片加载完成时触发
2629

27-
2830
### CSS Variables
31+
2932
组件提供了下列 CSS 变量,可用于自定义样式。
3033
名称 | 默认值 | 描述
3134
-- | -- | --
3235
--td-image-color | @font-gray-3 | -
3336
--td-image-loading-bg-color | @bg-color-secondarycontainer | -
3437
--td-image-loading-color | @font-gray-3 | -
35-
--td-image-round-radius | @radius-default | -
38+
--td-image-round-radius | @radius-default | -

src/image/image.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ref, computed, defineComponent, watchEffect } from 'vue';
22
import { useIntersectionObserver } from '@vueuse/core';
33
import { CloseIcon } from 'tdesign-icons-vue-next';
44

5-
import Loading from '../loading';
5+
import TLoading from '../loading';
66
import config from '../config';
77
import { useTNodeJSX } from '../hooks/tnode';
88
import { usePrefixClass } from '../hooks/useClass';
@@ -13,15 +13,14 @@ const { prefix } = config;
1313

1414
export default defineComponent({
1515
name: `${prefix}-image`,
16-
components: { CloseIcon, Loading },
1716
props,
1817
setup(props, context) {
1918
const imageClass = usePrefixClass('image');
2019
const renderTNodeJSX = useTNodeJSX();
2120

2221
// 默认loading和error状态展示,slot支持Node和Function
2322
const closeIcon = <CloseIcon size="22px" />;
24-
const LoadingIcon = <Loading theme="dots" inheritColor={true} />;
23+
const LoadingIcon = <TLoading theme="dots" inheritColor={true} />;
2524

2625
// 记录图片的loading、error状态
2726
const isLoading = ref(true);
@@ -67,6 +66,10 @@ export default defineComponent({
6766
props.onError?.({ e });
6867
isLoading.value = false;
6968
isError.value = true;
69+
if (props.fallback) {
70+
realSrc.value = props.fallback;
71+
isError.value = false;
72+
}
7073
};
7174

7275
const maskContent = computed(() => {
@@ -109,6 +112,7 @@ export default defineComponent({
109112
style={imageStyles.value}
110113
src={realSrc.value}
111114
alt={props.alt}
115+
referrerpolicy={props.referrerpolicy}
112116
onLoad={handleImgLoadCompleted}
113117
onError={handleImgLoadError}
114118
/>

src/image/props.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export default {
1717
error: {
1818
type: [String, Function] as PropType<TdImageProps['error']>,
1919
},
20+
/** 图片加载失败时,显示当前链接设置的图片地址。如果要使用组件图标或完全自定义加载失败时显示的内容,请更为使用 `error` */
21+
fallback: {
22+
type: String,
23+
default: '',
24+
},
2025
/** 图片填充模式 */
2126
fit: {
2227
type: String as PropType<TdImageProps['fit']>,
@@ -37,6 +42,23 @@ export default {
3742
type: String,
3843
default: 'center',
3944
},
45+
/** `<img>` 标签的原生属性,[MDN 定义](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) */
46+
referrerpolicy: {
47+
type: String as PropType<TdImageProps['referrerpolicy']>,
48+
validator(val: TdImageProps['referrerpolicy']): boolean {
49+
if (!val) return true;
50+
return [
51+
'no-referrer',
52+
'no-referrer-when-downgrade',
53+
'origin',
54+
'origin-when-cross-origin',
55+
'same-origin',
56+
'strict-origin',
57+
'strict-origin-when-cross-origin',
58+
'unsafe-url',
59+
].includes(val);
60+
},
61+
},
4062
/** 图片圆角类型 */
4163
shape: {
4264
type: String as PropType<TdImageProps['shape']>,
@@ -51,7 +73,7 @@ export default {
5173
type: String,
5274
default: '',
5375
},
54-
/** 图片地址,支持特殊格式的图片,如 `.avif` 和 `.webp` */
76+
/** 图片链接集合,用于支持特殊格式的图片,如 `.avif` 和 `.webp`。会优先加载 `srcset` 中的图片格式,浏览器不支持的情况下,加载 `src` 设置的图片地址 */
5577
srcset: {
5678
type: Object as PropType<TdImageProps['srcset']>,
5779
},

src/image/type.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ export interface TdImageProps {
1616
* 自定义图片加载失败状态下的显示内容
1717
*/
1818
error?: string | TNode;
19+
/**
20+
* 图片加载失败时,显示当前链接设置的图片地址。如果要使用组件图标或完全自定义加载失败时显示的内容,请更为使用 `error`
21+
* @default ''
22+
*/
23+
fallback?: string;
1924
/**
2025
* 图片填充模式
2126
* @default fill
@@ -35,6 +40,18 @@ export interface TdImageProps {
3540
* @default center
3641
*/
3742
position?: string;
43+
/**
44+
* `<img>` 标签的原生属性,[MDN 定义](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy)
45+
*/
46+
referrerpolicy?:
47+
| 'no-referrer'
48+
| 'no-referrer-when-downgrade'
49+
| 'origin'
50+
| 'origin-when-cross-origin'
51+
| 'same-origin'
52+
| 'strict-origin'
53+
| 'strict-origin-when-cross-origin'
54+
| 'unsafe-url';
3855
/**
3956
* 图片圆角类型
4057
* @default square
@@ -46,7 +63,7 @@ export interface TdImageProps {
4663
*/
4764
src?: string;
4865
/**
49-
* 图片地址,支持特殊格式的图片,如 `.avif` 和 `.webp`
66+
* 图片链接集合,用于支持特殊格式的图片,如 `.avif` 和 `.webp`。会优先加载 `srcset` 中的图片格式,浏览器不支持的情况下,加载 `src` 设置的图片地址
5067
*/
5168
srcset?: ImageSrcset;
5269
/**

0 commit comments

Comments
 (0)