Skip to content

Commit

Permalink
feat(image): support fallback and referrerpolicy (#1647)
Browse files Browse the repository at this point in the history
* feat(image): support  referrerpolicy

* feat(image): support  fallback

* test: add fallback test case
  • Loading branch information
liweijie0812 authored Nov 20, 2024
1 parent 687226b commit ed37554
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 14 deletions.
10 changes: 10 additions & 0 deletions src/image/__test__/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ describe('Image', () => {
expect(onError).toBeCalledTimes(0);
});

it(': fallback', async () => {
const onError = vi.fn();
const wrapper = mount(() => <Image src={FAIL_IMAGE} fallback={IMAGE} onError={onError} />);
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 = {
Expand Down
12 changes: 7 additions & 5 deletions src/image/image.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ 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
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
position | String | center | \- | N
shape | String | square | options:circle/round/square | N
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
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`<br/>trigger on image load failed | N
onLoad | Function | | Typescript:`(context: { e: ImageEvent }) => void`<br/>trigger on image loaded | N

Expand All @@ -25,12 +27,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 | -
11 changes: 7 additions & 4 deletions src/image/image.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
:: 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
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
position | String | center | 等同于原生的 object-position 属性,可选值为 top right bottom left 或 string,可以自定义任何单位,px 或者 百分比 | N
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
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`<br/>图片加载失败时触发 | N
onLoad | Function | | TS 类型:`(context: { e: ImageEvent }) => void`<br/>图片加载完成时触发 | N

Expand All @@ -24,12 +27,12 @@ onLoad | Function | | TS 类型:`(context: { e: ImageEvent }) => void`<br/>
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 | -
10 changes: 7 additions & 3 deletions src/image/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -13,15 +13,14 @@ const { prefix } = config;

export default defineComponent({
name: `${prefix}-image`,
components: { CloseIcon, Loading },
props,
setup(props, context) {
const imageClass = usePrefixClass('image');
const renderTNodeJSX = useTNodeJSX();

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

// 记录图片的loading、error状态
const isLoading = ref(true);
Expand Down Expand Up @@ -67,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(() => {
Expand Down Expand Up @@ -109,6 +112,7 @@ export default defineComponent({
style={imageStyles.value}
src={realSrc.value}
alt={props.alt}
referrerpolicy={props.referrerpolicy}
onLoad={handleImgLoadCompleted}
onError={handleImgLoadError}
/>
Expand Down
24 changes: 23 additions & 1 deletion src/image/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export default {
error: {
type: [String, Function] as PropType<TdImageProps['error']>,
},
/** 图片加载失败时,显示当前链接设置的图片地址。如果要使用组件图标或完全自定义加载失败时显示的内容,请更为使用 `error` */
fallback: {
type: String,
default: '',
},
/** 图片填充模式 */
fit: {
type: String as PropType<TdImageProps['fit']>,
Expand All @@ -37,6 +42,23 @@ export default {
type: String,
default: 'center',
},
/** `<img>` 标签的原生属性,[MDN 定义](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) */
referrerpolicy: {
type: String as PropType<TdImageProps['referrerpolicy']>,
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<TdImageProps['shape']>,
Expand All @@ -51,7 +73,7 @@ export default {
type: String,
default: '',
},
/** 图片地址,支持特殊格式的图片,如 `.avif` 和 `.webp` */
/** 图片链接集合,用于支持特殊格式的图片,如 `.avif` 和 `.webp`。会优先加载 `srcset` 中的图片格式,浏览器不支持的情况下,加载 `src` 设置的图片地址 */
srcset: {
type: Object as PropType<TdImageProps['srcset']>,
},
Expand Down
19 changes: 18 additions & 1 deletion src/image/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export interface TdImageProps {
* 自定义图片加载失败状态下的显示内容
*/
error?: string | TNode;
/**
* 图片加载失败时,显示当前链接设置的图片地址。如果要使用组件图标或完全自定义加载失败时显示的内容,请更为使用 `error`
* @default ''
*/
fallback?: string;
/**
* 图片填充模式
* @default fill
Expand All @@ -35,6 +40,18 @@ export interface TdImageProps {
* @default center
*/
position?: string;
/**
* `<img>` 标签的原生属性,[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
Expand All @@ -46,7 +63,7 @@ export interface TdImageProps {
*/
src?: string;
/**
* 图片地址,支持特殊格式的图片,如 `.avif` 和 `.webp`
* 图片链接集合,用于支持特殊格式的图片,如 `.avif` 和 `.webp`。会优先加载 `srcset` 中的图片格式,浏览器不支持的情况下,加载 `src` 设置的图片地址
*/
srcset?: ImageSrcset;
/**
Expand Down

0 comments on commit ed37554

Please sign in to comment.