From 7d3a73a7110242395090479addfc1aa2707fa3db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com>
Date: Tue, 19 Nov 2024 22:10:18 +0800
Subject: [PATCH 1/3] feat(image): support referrerpolicy
---
src/image/image.en-US.md | 11 ++++++-----
src/image/image.md | 10 ++++++----
src/image/image.tsx | 6 +++---
src/image/props.ts | 19 ++++++++++++++++++-
src/image/type.ts | 14 +++++++++++++-
5 files changed, 46 insertions(+), 14 deletions(-)
diff --git a/src/image/image.en-US.md b/src/image/image.en-US.md
index ed116611f..76a325017 100644
--- a/src/image/image.en-US.md
+++ b/src/image/image.en-US.md
@@ -8,13 +8,14 @@ name | type | default | description | required
-- | -- | -- | -- | --
alt | String | - | \- | N
error | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
-fit | String | fill | options:contain/cover/fill/none/scale-down | N
+fit | String | fill | options: contain/cover/fill/none/scale-down | N
lazy | Boolean | false | \- | N
loading | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
position | String | center | \- | N
-shape | String | square | options:circle/round/square | N
+referrerpolicy | String | - | attribute of ``, [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
+shape | String | square | options: circle/round/square | N
src | String | - | \- | N
-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
+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
onError | Function | | Typescript:`(context: { e: ImageEvent }) => void`
trigger on image load failed | N
onLoad | Function | | Typescript:`(context: { e: ImageEvent }) => void`
trigger on image loaded | N
@@ -25,12 +26,12 @@ name | params | description
error | `(context: { e: ImageEvent })` | trigger on image load failed
load | `(context: { e: ImageEvent })` | trigger on image loaded
-
### CSS Variables
+
The component provides the following CSS variables, which can be used to customize styles.
Name | Default Value | Description
-- | -- | --
--td-image-color | @font-gray-3 | -
--td-image-loading-bg-color | @bg-color-secondarycontainer | -
--td-image-loading-color | @font-gray-3 | -
---td-image-round-radius | @radius-default | -
+--td-image-round-radius | @radius-default | -
\ No newline at end of file
diff --git a/src/image/image.md b/src/image/image.md
index 4fedd6865..7f31ffb8d 100644
--- a/src/image/image.md
+++ b/src/image/image.md
@@ -1,9 +1,10 @@
:: BASE_DOC ::
## API
+
### Image Props
-名称 | 类型 | 默认值 | 说明 | 必传
+名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
alt | String | - | 图片描述 | N
error | String / Slot / Function | - | 自定义图片加载失败状态下的显示内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
@@ -11,9 +12,10 @@ fit | String | fill | 图片填充模式。可选项:contain/cover/fill/none/s
lazy | Boolean | false | 是否开启图片懒加载 | N
loading | String / Slot / Function | - | 自定义加载中状态的图片内容,如:“加载中”。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
position | String | center | 等同于原生的 object-position 属性,可选值为 top right bottom left 或 string,可以自定义任何单位,px 或者 百分比 | N
+referrerpolicy | String | - | `` 标签的原生属性,[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
shape | String | square | 图片圆角类型。可选项:circle/round/square | N
src | String | - | 图片链接 | N
-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
+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
onError | Function | | TS 类型:`(context: { e: ImageEvent }) => void`
图片加载失败时触发 | N
onLoad | Function | | TS 类型:`(context: { e: ImageEvent }) => void`
图片加载完成时触发 | N
@@ -24,12 +26,12 @@ onLoad | Function | | TS 类型:`(context: { e: ImageEvent }) => void`
error | `(context: { e: ImageEvent })` | 图片加载失败时触发
load | `(context: { e: ImageEvent })` | 图片加载完成时触发
-
### CSS Variables
+
组件提供了下列 CSS 变量,可用于自定义样式。
名称 | 默认值 | 描述
-- | -- | --
--td-image-color | @font-gray-3 | -
--td-image-loading-bg-color | @bg-color-secondarycontainer | -
--td-image-loading-color | @font-gray-3 | -
---td-image-round-radius | @radius-default | -
+--td-image-round-radius | @radius-default | -
\ No newline at end of file
diff --git a/src/image/image.tsx b/src/image/image.tsx
index c1b76022c..1cf85eed6 100644
--- a/src/image/image.tsx
+++ b/src/image/image.tsx
@@ -2,7 +2,7 @@ import { ref, computed, defineComponent, watchEffect } from 'vue';
import { useIntersectionObserver } from '@vueuse/core';
import { CloseIcon } from 'tdesign-icons-vue-next';
-import Loading from '../loading';
+import TLoading from '../loading';
import config from '../config';
import { useTNodeJSX } from '../hooks/tnode';
import { usePrefixClass } from '../hooks/useClass';
@@ -13,7 +13,6 @@ const { prefix } = config;
export default defineComponent({
name: `${prefix}-image`,
- components: { CloseIcon, Loading },
props,
setup(props, context) {
const imageClass = usePrefixClass('image');
@@ -21,7 +20,7 @@ export default defineComponent({
// 默认loading和error状态展示,slot支持Node和Function
const closeIcon = ;
- const LoadingIcon = ;
+ const LoadingIcon = ;
// 记录图片的loading、error状态
const isLoading = ref(true);
@@ -109,6 +108,7 @@ export default defineComponent({
style={imageStyles.value}
src={realSrc.value}
alt={props.alt}
+ referrerpolicy={props.referrerpolicy}
onLoad={handleImgLoadCompleted}
onError={handleImgLoadError}
/>
diff --git a/src/image/props.ts b/src/image/props.ts
index 19190ce0e..863b1e65f 100644
--- a/src/image/props.ts
+++ b/src/image/props.ts
@@ -37,6 +37,23 @@ export default {
type: String,
default: 'center',
},
+ /** `` 标签的原生属性,[MDN 定义](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) */
+ referrerpolicy: {
+ type: String as PropType,
+ validator(val: TdImageProps['referrerpolicy']): boolean {
+ if (!val) return true;
+ return [
+ 'no-referrer',
+ 'no-referrer-when-downgrade',
+ 'origin',
+ 'origin-when-cross-origin',
+ 'same-origin',
+ 'strict-origin',
+ 'strict-origin-when-cross-origin',
+ 'unsafe-url',
+ ].includes(val);
+ },
+ },
/** 图片圆角类型 */
shape: {
type: String as PropType,
@@ -51,7 +68,7 @@ export default {
type: String,
default: '',
},
- /** 图片地址,支持特殊格式的图片,如 `.avif` 和 `.webp` */
+ /** 图片链接集合,用于支持特殊格式的图片,如 `.avif` 和 `.webp`。会优先加载 `srcset` 中的图片格式,浏览器不支持的情况下,加载 `src` 设置的图片地址 */
srcset: {
type: Object as PropType,
},
diff --git a/src/image/type.ts b/src/image/type.ts
index e473443f5..b5929dea6 100644
--- a/src/image/type.ts
+++ b/src/image/type.ts
@@ -35,6 +35,18 @@ export interface TdImageProps {
* @default center
*/
position?: string;
+ /**
+ * `` 标签的原生属性,[MDN 定义](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy)
+ */
+ referrerpolicy?:
+ | 'no-referrer'
+ | 'no-referrer-when-downgrade'
+ | 'origin'
+ | 'origin-when-cross-origin'
+ | 'same-origin'
+ | 'strict-origin'
+ | 'strict-origin-when-cross-origin'
+ | 'unsafe-url';
/**
* 图片圆角类型
* @default square
@@ -46,7 +58,7 @@ export interface TdImageProps {
*/
src?: string;
/**
- * 图片地址,支持特殊格式的图片,如 `.avif` 和 `.webp`
+ * 图片链接集合,用于支持特殊格式的图片,如 `.avif` 和 `.webp`。会优先加载 `srcset` 中的图片格式,浏览器不支持的情况下,加载 `src` 设置的图片地址
*/
srcset?: ImageSrcset;
/**
From b0b8e3ec7e2966876fbfd303c2bef1be7524851a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com>
Date: Tue, 19 Nov 2024 22:20:22 +0800
Subject: [PATCH 2/3] feat(image): support fallback
---
src/image/image.en-US.md | 1 +
src/image/image.md | 1 +
src/image/image.tsx | 4 ++++
src/image/props.ts | 5 +++++
src/image/type.ts | 5 +++++
5 files changed, 16 insertions(+)
diff --git a/src/image/image.en-US.md b/src/image/image.en-US.md
index 76a325017..f92617e3b 100644
--- a/src/image/image.en-US.md
+++ b/src/image/image.en-US.md
@@ -8,6 +8,7 @@ name | type | default | description | required
-- | -- | -- | -- | --
alt | String | - | \- | N
error | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+fallback | String | - | display `fallback` image on `src` loading failed. you can also use `error` to define more complex error content | N
fit | String | fill | options: contain/cover/fill/none/scale-down | N
lazy | Boolean | false | \- | N
loading | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
diff --git a/src/image/image.md b/src/image/image.md
index 7f31ffb8d..3545dc77c 100644
--- a/src/image/image.md
+++ b/src/image/image.md
@@ -8,6 +8,7 @@
-- | -- | -- | -- | --
alt | String | - | 图片描述 | N
error | String / Slot / Function | - | 自定义图片加载失败状态下的显示内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+fallback | String | - | 图片加载失败时,显示当前链接设置的图片地址。如果要使用组件图标或完全自定义加载失败时显示的内容,请更为使用 `error` | N
fit | String | fill | 图片填充模式。可选项:contain/cover/fill/none/scale-down | N
lazy | Boolean | false | 是否开启图片懒加载 | N
loading | String / Slot / Function | - | 自定义加载中状态的图片内容,如:“加载中”。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
diff --git a/src/image/image.tsx b/src/image/image.tsx
index 1cf85eed6..a7d40680b 100644
--- a/src/image/image.tsx
+++ b/src/image/image.tsx
@@ -66,6 +66,10 @@ export default defineComponent({
props.onError?.({ e });
isLoading.value = false;
isError.value = true;
+ if (props.fallback) {
+ realSrc.value = props.fallback;
+ isError.value = false;
+ }
};
const maskContent = computed(() => {
diff --git a/src/image/props.ts b/src/image/props.ts
index 863b1e65f..32b305ed1 100644
--- a/src/image/props.ts
+++ b/src/image/props.ts
@@ -17,6 +17,11 @@ export default {
error: {
type: [String, Function] as PropType,
},
+ /** 图片加载失败时,显示当前链接设置的图片地址。如果要使用组件图标或完全自定义加载失败时显示的内容,请更为使用 `error` */
+ fallback: {
+ type: String,
+ default: '',
+ },
/** 图片填充模式 */
fit: {
type: String as PropType,
diff --git a/src/image/type.ts b/src/image/type.ts
index b5929dea6..dab08bf58 100644
--- a/src/image/type.ts
+++ b/src/image/type.ts
@@ -16,6 +16,11 @@ export interface TdImageProps {
* 自定义图片加载失败状态下的显示内容
*/
error?: string | TNode;
+ /**
+ * 图片加载失败时,显示当前链接设置的图片地址。如果要使用组件图标或完全自定义加载失败时显示的内容,请更为使用 `error`
+ * @default ''
+ */
+ fallback?: string;
/**
* 图片填充模式
* @default fill
From 0373f6823d6a0f36ff670433deab204c48898b75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com>
Date: Tue, 19 Nov 2024 22:36:50 +0800
Subject: [PATCH 3/3] test: add fallback test case
---
src/image/__test__/index.test.jsx | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/image/__test__/index.test.jsx b/src/image/__test__/index.test.jsx
index 9e60b70e4..41b4a62ea 100644
--- a/src/image/__test__/index.test.jsx
+++ b/src/image/__test__/index.test.jsx
@@ -114,6 +114,16 @@ describe('Image', () => {
expect(onError).toBeCalledTimes(0);
});
+ it(': fallback', async () => {
+ const onError = vi.fn();
+ const wrapper = mount(() => );
+ await nextTick();
+ const $image = wrapper.find(`.${name}__img`);
+ // 手动触发 图片加载失败的回调函数
+ await $image.trigger('error');
+ expect($image.attributes('src')).toBe(IMAGE);
+ });
+
it(': onError', async () => {
const onError = vi.fn();
const slots = {