From 8c26036e60b218e2cca152327c506df16eedc63e Mon Sep 17 00:00:00 2001 From: bqy_fe <1743369777@qq.com> Date: Wed, 30 Mar 2022 21:44:30 +0800 Subject: [PATCH] refactor(components): [image, image-viewer] refactor (#6704) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 三咲智子 --- docs/en-US/component/image.md | 83 +-- .../image-viewer/src/image-viewer.ts | 6 + .../image-viewer/src/image-viewer.vue | 520 ++++++++---------- .../{image.spec.ts => image.spec.tsx} | 84 +-- packages/components/image/src/image.vue | 407 +++++++------- 5 files changed, 524 insertions(+), 576 deletions(-) rename packages/components/image/__tests__/{image.spec.ts => image.spec.tsx} (70%) diff --git a/docs/en-US/component/image.md b/docs/en-US/component/image.md index df4941538a..684d80a1a9 100644 --- a/docs/en-US/component/image.md +++ b/docs/en-US/component/image.md @@ -47,50 +47,57 @@ image/image-preview ::: -## Image Attributes +## Image API -| Attribute | Description | Type | Accepted values | Default | -| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | ------------------------------------------ | ---------------------------------------------------------------------- | -| alt | Native alt | 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) | string | 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 | true / false | false | -| initial-index | The initial preview image index, less than the length of `url-list` | number | int | 0 | -| lazy | Whether to use lazy load | boolean | — | false | -| preview-src-list | allow big image preview | Array | — | - | -| referrer-policy | Native referrerPolicy | string | - | - | -| src | Image source, same as native | string | — | - | -| 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 | -| z-index | set image preview z-index | Number | — | 2000 | -| 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 Attributes -## Image Events +| 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` | +| `preview-teleported` | whether to append image-viewer to body. A nested parent element attribute transform should have this attribute set to `true`. | `boolean` | `false` | -| Event Name | Description | Parameters | -| ---------- | -------------------- | ---------- | -| load | Same as native load | (e: Event) | -| error | Same as native error | (e: Error) | +### Image Events -## Image Slots +| Name | Description | Type | +| -------- | ------------------------------------------------------------------------------------------------- | ------------------------- | +| `load` | same as native load. | `(e: Event) => void` | +| `error` | same as native error. | `(e: Error) => void` | +| `switch` | trigger when switching images. | `(index: number) => void` | +| `close` | trigger when clicking on close button or when `hide-on-click-modal` enabled clicking on backdrop. | `() => void` | -| Name | Description | -| ----------- | ------------------------------- | -| placeholder | Triggers when image load | -| error | Triggers when image load failed | +### Image Slots -## ImageViewer Attributes +| Name | Description | +| ------------- | -------------------------------- | +| `placeholder` | triggers when image load. | +| `error` | triggers when image load failed. | +| `viewer` | description of the image. | -| Attribute | Description | Type | Acceptable Value | Default | -| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------- | ------------------- | ------- | -| url-list | Preview link list | Array\ | - | [] | -| z-index | Preview backdrop z-index | number / string | int / string\ | 2000 | -| initial-index | The initial preview image index, less than or equal to the length of `url-list` | number | int | 0 | -| infinite | Whether preview is infinite | boolean | true / false | true | -| hide-on-click-modal | Whether user can emit close event when clicking backdrop | boolean | true / false | false | -| teleported | whether to append image itself to body. A nested parent element attribute transform should have this attribute set to `true` | boolean | — | false | +## Image Viewer API -## ImageViewer Events +### Image Viewer Attributes -| Event name | Description | Callback parameter | -| ---------- | ---------------------------------------------------------------------------------------------- | -------------------------------------- | -| close | Emitted when clicking on `X` button or when `hide-on-click-modal` enabled clicking on backdrop | None | -| switch | When switching images | `(val: number)` switching target index | +| Name | Description | Type | Default | +| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------ | ------- | +| `url-list` | preview link list. | `string[]` | `[]` | +| `z-index` | preview backdrop z-index. | `number \| string` | — | +| `initial-index` | the initial preview image index, less than or equal to the length of `url-list`. | `number` | `0` | +| `infinite` | whether preview is infinite. | `boolean` | `true` | +| `hide-on-click-modal` | whether user can emit close event when clicking backdrop. | `boolean` | `false` | +| `teleported` | whether to append image itself to body. A nested parent element attribute transform should have this attribute set to `true`. | `boolean` | `false` | + +### Image Viewer Events + +| Event name | Description | Type | +| ---------- | ------------------------------------------------------------------------------------------------- | ------------------------- | +| `close` | trigger when clicking on close button or when `hide-on-click-modal` enabled clicking on backdrop. | `() => void` | +| `switch` | trigger when switching images. | `(index: number) => void` | diff --git a/packages/components/image-viewer/src/image-viewer.ts b/packages/components/image-viewer/src/image-viewer.ts index 6485b76837..0bcc8d3226 100644 --- a/packages/components/image-viewer/src/image-viewer.ts +++ b/packages/components/image-viewer/src/image-viewer.ts @@ -1,6 +1,12 @@ import { buildProps, definePropType, mutable } from '@element-plus/utils' import type { ExtractPropTypes } from 'vue' +export type ImageViewerAction = + | 'zoomIn' + | 'zoomOut' + | 'clockwise' + | 'anticlockwise' + export const imageViewerProps = buildProps({ urlList: { type: definePropType(Array), diff --git a/packages/components/image-viewer/src/image-viewer.vue b/packages/components/image-viewer/src/image-viewer.vue index fcc096c13b..428faade30 100644 --- a/packages/components/image-viewer/src/image-viewer.vue +++ b/packages/components/image-viewer/src/image-viewer.vue @@ -11,7 +11,7 @@ - + @@ -24,7 +24,7 @@ ]" @click="prev" > - + - +
- + - + @@ -52,10 +52,10 @@ - + - +
@@ -80,10 +80,9 @@ - diff --git a/packages/components/image/__tests__/image.spec.ts b/packages/components/image/__tests__/image.spec.tsx similarity index 70% rename from packages/components/image/__tests__/image.spec.ts rename to packages/components/image/__tests__/image.spec.tsx index 076bae6ded..96e5fd86ef 100644 --- a/packages/components/image/__tests__/image.spec.ts +++ b/packages/components/image/__tests__/image.spec.tsx @@ -6,6 +6,12 @@ import { mockImageEvent, } from '@element-plus/test-utils/mock' import Image from '../src/image.vue' +import type { AnchorHTMLAttributes, ImgHTMLAttributes } from 'vue' +import type { ImageProps } from '../src/image' + +type ElImageProps = ImgHTMLAttributes & + AnchorHTMLAttributes & + Partial // firstly wait for image event // secondly wait for vue render @@ -24,10 +30,13 @@ describe('Image.vue', () => { test('image load success test', async () => { const alt = 'this ia alt' - const wrapper = mount(Image, { - props: { - src: IMAGE_SUCCESS, - alt, + const wrapper = mount({ + setup() { + const props: ElImageProps = { + alt, + src: IMAGE_SUCCESS, + } + return () => }, }) expect(wrapper.find('.el-image__placeholder').exists()).toBe(true) @@ -70,11 +79,9 @@ describe('Image.vue', () => { }) test('imageStyle fit test', async () => { - const fits = ['fill', 'contain', 'cover', 'none', 'scale-down'] + const fits = ['fill', 'contain', 'cover', 'none', 'scale-down'] as const for (const fit of fits) { - const wrapper = mount(Image, { - props: { fit, src: IMAGE_SUCCESS }, - }) + const wrapper = mount(() => ) await doubleWait() expect(wrapper.find('img').attributes('style')).toContain( `object-fit: ${fit};` @@ -83,25 +90,23 @@ describe('Image.vue', () => { }) test('preview classname test', async () => { - const wrapper = mount(Image, { - props: { - fit: 'cover', - src: IMAGE_SUCCESS, - previewSrcList: Array.from({ length: 3 }).fill(IMAGE_SUCCESS), - }, - }) + const props: ElImageProps = { + fit: 'cover', + src: IMAGE_SUCCESS, + previewSrcList: Array.from({ length: 3 }).fill(IMAGE_SUCCESS), + } + const wrapper = mount(() => ) await doubleWait() expect(wrapper.find('img').classes()).toContain('el-image__preview') }) test('preview initial index test', async () => { - const wrapper = mount(Image, { - props: { - src: IMAGE_SUCCESS, - previewSrcList: Array.from({ length: 3 }).fill(IMAGE_FAIL), - initialIndex: 1, - }, - }) + const props: ElImageProps = { + src: IMAGE_SUCCESS, + previewSrcList: Array.from({ length: 3 }).fill(IMAGE_FAIL), + initialIndex: 1, + } + const wrapper = mount(() => ) await doubleWait() await wrapper.find('.el-image__inner').trigger('click') expect( @@ -111,13 +116,12 @@ describe('Image.vue', () => { test('$attrs', async () => { const alt = 'this ia alt' - const wrapper = mount(Image, { - props: { - src: IMAGE_SUCCESS, - alt, - referrerpolicy: 'origin', - }, - }) + const props: ElImageProps = { + alt, + src: IMAGE_SUCCESS, + referrerpolicy: 'origin', + } + const wrapper = mount(() => ) await doubleWait() expect(wrapper.find('img').attributes('alt')).toBe(alt) expect(wrapper.find('img').attributes('referrerpolicy')).toBe('origin') @@ -125,12 +129,11 @@ describe('Image.vue', () => { test('pass event listeners', async () => { let result = false - const wrapper = mount(Image, { - props: { - src: IMAGE_SUCCESS, - onClick: () => (result = true), - }, - }) + const props: ElImageProps = { + src: IMAGE_SUCCESS, + onClick: () => (result = true), + } + const wrapper = mount(() => ) await doubleWait() await wrapper.find('.el-image__inner').trigger('click') expect(result).toBeTruthy() @@ -138,12 +141,11 @@ describe('Image.vue', () => { test('emit load event', async () => { const handleLoad = jest.fn() - const wrapper = mount(Image, { - props: { - src: IMAGE_SUCCESS, - onLoad: handleLoad, - }, - }) + const props: ElImageProps = { + src: IMAGE_SUCCESS, + onLoad: handleLoad, + } + const wrapper = mount(() => ) await doubleWait() expect(wrapper.find('.el-image__inner').exists()).toBe(true) expect(handleLoad).toBeCalled() diff --git a/packages/components/image/src/image.vue b/packages/components/image/src/image.vue index 4c42646665..29bf54f596 100644 --- a/packages/components/image/src/image.vue +++ b/packages/components/image/src/image.vue @@ -33,9 +33,8 @@ -