From 60cd22b890558247983f2001185a581e18421b01 Mon Sep 17 00:00:00 2001 From: qiang Date: Wed, 1 Jun 2022 13:21:05 +0800 Subject: [PATCH] feat(components): [image] support native lazy loading (#7968) --- breakings/2.2.3/image.yml | 12 +++ docs/en-US/component/image.md | 37 +++++---- .../components/image/__tests__/image.test.tsx | 16 ++++ packages/components/image/src/image.ts | 4 + packages/components/image/src/image.vue | 77 +++++++------------ packages/theme-chalk/src/image.scss | 8 ++ 6 files changed, 92 insertions(+), 62 deletions(-) create mode 100644 breakings/2.2.3/image.yml diff --git a/breakings/2.2.3/image.yml b/breakings/2.2.3/image.yml new file mode 100644 index 0000000000..0c0b3c64b9 --- /dev/null +++ b/breakings/2.2.3/image.yml @@ -0,0 +1,12 @@ +- scope: 'component' + name: 'el-image' + type: 'props' + version: '2.2.3' + commit_hash: '7a48556' + description: | + Per [HTMLImageElement.loading Request](https://github.com/element-plus/element-plus/issues/7841), + Add [native loading](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading) support for Image components. + props: + - api: 'loading' + before: '' + after: '"eager" | "lazy"' diff --git a/docs/en-US/component/image.md b/docs/en-US/component/image.md index e467f6855d..1aecad53c8 100644 --- a/docs/en-US/component/image.md +++ b/docs/en-US/component/image.md @@ -33,6 +33,14 @@ image/load-failed ## Lazy Load +:::tip + +Native `loading` has been supported since , you can use `loading = "lazy"` to replace `lazy = true`. + +If the current browser supports native lazy loading, the native lazy loading will be used first, otherwise will be implemented through scroll. + +::: + :::demo Use lazy load by `lazy = true`. Image will load until scroll into view when set. You can indicate scroll container that adds scroll listener to by `scroll-container`. If undefined, will be the nearest parent container whose overflow property is auto or scroll. image/lazy-load @@ -51,20 +59,21 @@ image/image-preview ### Image Attributes -| Name | Description | Type | Default | -| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------- | -| `src` | image source, same as native. | `string` | — | -| `fit` | indicate how the image should be resized to fit its container, same as [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit). | `'fill' \| 'contain' \| 'cover' \| 'none' \| 'scale'-down'` | — | -| `hide-on-click-modal` | when enabling preview, use this flag to control whether clicking on backdrop can exit preview mode. | `boolean` | `false` | -| `lazy` | whether to use lazy load. | `boolean` | `false` | -| `scroll-container` | the container to add scroll listener when using lazy load. | `string \| HTMLElement` | the nearest parent container whose overflow property is auto or scroll. | -| `alt` | native attribute `alt`. | `string` | — | -| `referrer-policy` | native attribute `referrerPolicy`. | `string` | — | -| `preview-src-list` | allow big image preview. | `string[]` | — | -| `z-index` | set image preview z-index. | `number` | — | -| `initial-index` | initial preview image index, less than the length of `url-list`. | `number` | `0` | -| `close-on-press-escape` | whether the image-viewer can be closed by pressing ESC | `boolean` | `true` | -| `preview-teleported` | whether to append image-viewer to body. A nested parent element attribute transform should have this attribute set to `true`. | `boolean` | `false` | +| Attribute | Description | Type | Default | +| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------- | +| `src` | image source, same as native. | `string` | — | +| `fit` | indicate how the image should be resized to fit its container, same as [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit). | `'fill' \| 'contain' \| 'cover' \| 'none' \| 'scale'-down'` | — | +| `hide-on-click-modal` | when enabling preview, use this flag to control whether clicking on backdrop can exit preview mode. | `boolean` | `false` | +| `loading` | Indicates how the browser should load the image, same as [native](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading) | `'eager' \| 'lazy'` | — | +| `lazy` | whether to use lazy load. | `boolean` | `false` | +| `scroll-container` | the container to add scroll listener when using lazy load. | `string \| HTMLElement` | the nearest parent container whose overflow property is auto or scroll. | +| `alt` | native attribute `alt`. | `string` | — | +| `referrer-policy` | native attribute `referrerPolicy`. | `string` | — | +| `preview-src-list` | allow big image preview. | `string[]` | — | +| `z-index` | set image preview z-index. | `number` | — | +| `initial-index` | initial preview image index, less than the length of `url-list`. | `number` | `0` | +| `close-on-press-escape` | whether the image-viewer can be closed by pressing ESC | `boolean` | `true` | +| `preview-teleported` | whether to append image-viewer to body. A nested parent element attribute transform should have this attribute set to `true`. | `boolean` | `false` | ### Image Events diff --git a/packages/components/image/__tests__/image.test.tsx b/packages/components/image/__tests__/image.test.tsx index 075ed81422..af54622dc8 100644 --- a/packages/components/image/__tests__/image.test.tsx +++ b/packages/components/image/__tests__/image.test.tsx @@ -115,6 +115,22 @@ describe('Image.vue', () => { ).not.toContain('display: none') }) + test('native loading attributes', async () => { + const wrapper = mount(Image, { + props: { + src: IMAGE_SUCCESS, + loading: 'eager', + } as ElImageProps, + }) + + await doubleWait() + expect(wrapper.find('img').exists()).toBe(true) + expect(wrapper.find('img').attributes('loading')).toBe('eager') + + await wrapper.setProps({ loading: undefined }) + expect(wrapper.find('img').attributes('loading')).toBe(undefined) + }) + test('$attrs', async () => { const alt = 'this ia alt' const props: ElImageProps = { diff --git a/packages/components/image/src/image.ts b/packages/components/image/src/image.ts index 59a17d3857..39301cbd37 100644 --- a/packages/components/image/src/image.ts +++ b/packages/components/image/src/image.ts @@ -21,6 +21,10 @@ export const imageProps = buildProps({ values: ['', 'contain', 'cover', 'fill', 'none', 'scale-down'], default: '', }, + loading: { + type: String, + values: ['eager', 'lazy'], + }, lazy: { type: Boolean, default: false, diff --git a/packages/components/image/src/image.vue b/packages/components/image/src/image.vue index 63de73eae4..90e3bf03bb 100644 --- a/packages/components/image/src/image.vue +++ b/packages/components/image/src/image.vue @@ -1,19 +1,22 @@