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;