From 7715a1ed5e89acfdbac2c9714c6ddaf2d15516e3 Mon Sep 17 00:00:00 2001 From: hbztd <38969912+hbztd@users.noreply.github.com> Date: Sun, 21 Jul 2024 15:56:26 +0800 Subject: [PATCH] feat(Image): add width and height; fix placeholder does not work --- packages/core/src/image/README.md | 42 +++++++------ packages/core/src/image/image.scss | 5 -- packages/core/src/image/image.tsx | 59 ++++++++----------- .../demo/src/pages/basic/image/index.scss | 11 +--- packages/demo/src/pages/basic/image/index.tsx | 46 +++++++-------- .../demo/src/pages/display/empty/index.tsx | 1 + .../demo/src/pages/form/uploader/index.scss | 1 + 7 files changed, 71 insertions(+), 94 deletions(-) diff --git a/packages/core/src/image/README.md b/packages/core/src/image/README.md index 316b72e83..fff31fa72 100644 --- a/packages/core/src/image/README.md +++ b/packages/core/src/image/README.md @@ -14,10 +14,12 @@ import { Image } from "@taroify/core" ### 基础用法 -基础用法与原生 `img` 标签一致,可以设置 `src`、`alt` 等原生属性。 +基础用法与原生 `img` 标签一致,可以设置 `src`、`alt` 等原生属性。
+通过 `width` 和 `height` 设置图片大小,若未指定,会从style中读取`width`,`height`属性。
+width和height若为number, 会经过 `pxTransform` 转换 ```tsx - + ``` ### 填充模式 @@ -26,7 +28,8 @@ import { Image } from "@taroify/core" ```tsx @@ -38,8 +41,9 @@ import { Image } from "@taroify/core" ```tsx ``` @@ -51,25 +55,23 @@ import { Image } from "@taroify/core" ```tsx ``` -### 加载中提示 +### 加载中,加载失败提示 -`Image` 组件提供了默认的加载中提示,支持通过 `placeholder` 插槽自定义内容。 +通过 `placeholder` 设置加载中提示,通过 `fallback`设置加载失败提示 ```tsx - -``` - -### 加载失败提示 +import { Photo, PhotoFail } from "@taroify/icons" -`Image` 组件提供了默认的加载失败提示,支持通过 `fallback` 插槽自定义内容。 - -```tsx - + + +} /> +} /> ``` ## API @@ -79,12 +81,14 @@ import { Image } from "@taroify/core" | 参数 | 说明 | 类型 | 默认值 | |-------------|-------------------------------------|-------------|-----------------| | src | 图片链接 | _string_ | - | -| mode | 图片填充模式 | _string_ | `fill` | +| mode | 图片填充模式 | _string_ | `scaleToFill` | | alt | 替代文本 | _string_ | - | +| width | 宽度 | _string\|number_ | - | +| height | 长度 | _string\|number_ | - | | shape | 图片形状 `square` `rounded` `circle` | _boolean_ | - | | lazyLoad | 是否开启图片懒加载 | _boolean_ | `false` | -| placeholder | 加载时提示的[图标名称](/components/icon)或图片链接 | _ReactNode_ | `` | -| fallback | 失败时提示的[图标名称](/components/icon)或图片链接 | _ReactNode_ | `` | +| placeholder | 加载中提示 | _ReactNode_ | - | +| fallback | 加载失败提示 | _ReactNode_ | - | ### Modes diff --git a/packages/core/src/image/image.scss b/packages/core/src/image/image.scss index bb9310737..b6d17166f 100644 --- a/packages/core/src/image/image.scss +++ b/packages/core/src/image/image.scss @@ -1,11 +1,6 @@ @import "./variables"; .#{$component-prefix}image { - position: relative; - display: inline-block; - width: 100%; - height: 100%; - &--circle { overflow: hidden; border-radius: 50%; diff --git a/packages/core/src/image/image.tsx b/packages/core/src/image/image.tsx index 09761c5be..4de13c24c 100644 --- a/packages/core/src/image/image.tsx +++ b/packages/core/src/image/image.tsx @@ -3,9 +3,11 @@ import classNames from "classnames" import * as _ from "lodash" import * as React from "react" import { ReactNode, useEffect, useMemo, useState, useRef } from "react" +import { pxTransform } from "@tarojs/taro" import { prefixClassname } from "../styles" import { getLogger } from "../utils/logger" import { useMemoizedFn } from "../hooks" +import mergeStyle from "../utils/merge-style" import ImagePlaceholder from "./image-placeholder" import { ImageMode, ImageShape } from "./image.shared" @@ -43,7 +45,10 @@ function useImageShape(shape?: ImageShape, round?: boolean) { export interface ImageProps extends ViewProps { src?: string alt?: string + width?: string | number + height?: string | number mode?: ImageMode + /** @deprecated */ round?: boolean shape?: ImageShape lazyLoad?: boolean @@ -60,14 +65,17 @@ export default function Image(props: ImageProps) { className, src, alt, + width: widthProp, + height: heightProp, mode = "scaleToFill", round, shape: shapeProp, lazyLoad = false, - placeholder = true, - fallback = true, + placeholder = false, + fallback = false, onLoad, onError, + style: styleProp, ...restProps } = props const taroImageRef = useRef() @@ -76,6 +84,16 @@ export default function Image(props: ImageProps) { const [loading, setLoading] = useState(false) const [failed, setFailed] = useState(false) const isLoadedRef = useRef(false) + + const [viewStyle, imgStyle] = useMemo(() => { + const width = widthProp ? typeof widthProp === "number" ? pxTransform(widthProp) : widthProp : undefined + const height = heightProp ? typeof heightProp === "number" ? pxTransform(heightProp) : heightProp : undefined + const imgStyle = mergeStyle(styleProp, {}) + imgStyle.width = width || imgStyle.width + imgStyle.height = height || imgStyle.height + return [{ width: imgStyle.width || "100%", height: imgStyle.height || "100%", position: "relative" }, imgStyle] as const + }, [styleProp, widthProp, heightProp]) + const handleLoad = useMemoizedFn(() => { if (!isLoadedRef.current) { isLoadedRef.current = true @@ -100,7 +118,7 @@ export default function Image(props: ImageProps) { // eslint-disable-next-line react-hooks/exhaustive-deps }, [src]) return ( - + {!failed && src && ( )} - {loading && placeholder && ( - - - - )} - {failed && fallback && ( - - - - )} + {loading && placeholder && } + {failed && fallback && } ) } diff --git a/packages/demo/src/pages/basic/image/index.scss b/packages/demo/src/pages/basic/image/index.scss index c52652494..74298b884 100644 --- a/packages/demo/src/pages/basic/image/index.scss +++ b/packages/demo/src/pages/basic/image/index.scss @@ -3,6 +3,7 @@ .image-demo { background: #fff; + overflow-y: auto; .#{$component-prefix}flex-item { margin-bottom: 10px * $hd; @@ -15,14 +16,4 @@ font-size: 14px * $hd; text-align: center; } - - .#{$component-prefix}image { - width: 100%; - height: 27vw; - } - - .basic-image { - width: 100px * $hd; - height: 100px * $hd; - } } diff --git a/packages/demo/src/pages/basic/image/index.tsx b/packages/demo/src/pages/basic/image/index.tsx index 62ccad767..3d9544910 100644 --- a/packages/demo/src/pages/basic/image/index.tsx +++ b/packages/demo/src/pages/basic/image/index.tsx @@ -15,27 +15,27 @@ export default function ImageDemo() { "aspectFill", "widthFix", "heightFix", - "top", - "bottom", - "center", - "left", - "right", - "topLeft", - "topRight", - "bottomLeft", - "bottomRight", + // "top", + // "bottom", + // "center", + // "left", + // "right", + // "topLeft", + // "topRight", + // "bottomLeft", + // "bottomRight", ] return ( - + {modes.map((mode) => ( - + {mode} ))} @@ -45,33 +45,29 @@ export default function ImageDemo() { {modes.map((mode) => ( - + {mode} ))} - + - } /> - 默认提示 + } /> + 加载提示 - - 自定义提示 + + 加载提示 - - - - - } /> - 默认提示 + } /> + 失败提示 - - 自定义提示 + + 失败提示 diff --git a/packages/demo/src/pages/display/empty/index.tsx b/packages/demo/src/pages/display/empty/index.tsx index b64d86ccf..5875cecb8 100644 --- a/packages/demo/src/pages/display/empty/index.tsx +++ b/packages/demo/src/pages/display/empty/index.tsx @@ -45,6 +45,7 @@ export default function EmptyDemo() { diff --git a/packages/demo/src/pages/form/uploader/index.scss b/packages/demo/src/pages/form/uploader/index.scss index 7c9e91ad2..25f8a65a9 100644 --- a/packages/demo/src/pages/form/uploader/index.scss +++ b/packages/demo/src/pages/form/uploader/index.scss @@ -4,6 +4,7 @@ .uploader-demo { background: #fff; + overflow-y: auto; .preview-cover { position: absolute;