Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ✨ img组件添加loading error插槽 #323

Merged
merged 1 commit into from
May 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 66 additions & 20 deletions docs/component/img.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<frame/>

# Img 图片
# Img 图片

增强版的 img 标签,提供多种图片填充模式,支持图片懒加载、加载完成、加载失败


## 基本用法

基础用法与原生 image 标签一致,可以设置 `src` 、 `width` 、`height` 等原生属性。
Expand All @@ -30,6 +29,46 @@
const joy = 'data:image/jpeg;base64,...' // 图片文件base64
```

## 插槽

使用`loading` `error`插槽设置在图片加载时、加载失败后的展示内容

```vue
<template>
<wd-img :width="100" :height="100" src="https://www.123.com/a.jpg">
<template #error>
<view class="error-wrap">
加载失败
</view>
</template>
<template #loading>
<view class="loading-wrap">
<wd-loading/>
</view>
</template>
</wd-img>
</template>

<style>
.error-wrap {
width: 100%;
height: 100%;
background-color: red;
color: white;
line-height: 100px;
text-align: center;
}

.loading-wrap {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>
```

## 填充模式

通过 `mode` 属性可以设置图片填充模式,可选值见下方表格。
Expand Down Expand Up @@ -73,27 +112,34 @@ mode为小程序原生属性,参考[微信小程序image官方文档](https://

## Attributes

| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
|-----|------|-----|-------|-------|---------|
| src | 图片链接 | string | - | - | - |
| width | 宽度,默认单位为px | number / string | - | - | - |
| height | 高度,默认单位为px | number / string | - | - | - |
| mode | 填充模式 | ImageMode | 'top left' / 'top right' / 'bottom left' / 'bottom right' / 'right' / 'left' / 'center' / 'bottom' / 'top' / 'heightFix' / 'widthFix' / 'aspectFill' / 'aspectFit' / 'scaleToFill' | 'scaleToFill' | - |
| round | 是否显示为圆形 | boolean | - | false | - |
| radius | 圆角大小,默认单位为px | number / string | - | - | - |
| enable-preview | 是否支持点击预览 | boolean | - | false | 1.2.11 |
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
| -------------- | ---------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------- |
| src | 图片链接 | string | - | - | - |
| width | 宽度,默认单位为px | number / string | - | - | - |
| height | 高度,默认单位为px | number / string | - | - | - |
| mode | 填充模式 | ImageMode | 'top left' / 'top right' / 'bottom left' / 'bottom right' / 'right' / 'left' / 'center' / 'bottom' / 'top' / 'heightFix' / 'widthFix' / 'aspectFill' / 'aspectFit' / 'scaleToFill' | 'scaleToFill' | - |
| round | 是否显示为圆形 | boolean | - | false | - |
| radius | 圆角大小,默认单位为px | number / string | - | - | - |
| enable-preview | 是否支持点击预览 | boolean | - | false | 1.2.11 |

## Events

| 事件名称 | 说明 | 参数 | 最低版本 |
|---------|-----|-----|---------|
| click | 点击事件 | - | - |
| load | 当图片载入完毕时触发 | ` {height, width}` | - |
| error | 当错误发生时触发 | `{errMsg}` | - |
| 事件名称 | 说明 | 参数 | 最低版本 |
| -------- | -------------------- | ----------------- | -------- |
| click | 点击事件 | - | - |
| load | 当图片载入完毕时触发 | `{height, width}` | - |
| error | 当错误发生时触发 | `{errMsg}` | - |

## Slots

| 名称 | 说明 | 最低版本 |
| ------- | ------------------ | ---------------- |
| loading | 图片加载时展示 | $LOWEST_VERSION$ |
| error | 图片加载失败后展示 | $LOWEST_VERSION$ |

## 外部样式类

| 类名 | 说明 | 最低版本 |
|-----|------|--------|
| custom-class | 根节点样式 | - |
| custom-image| image 外部自定义样式 | - |
| 类名 | 说明 | 最低版本 |
| ------------ | -------------------- | -------- |
| custom-class | 根节点样式 | - |
| custom-image | image 外部自定义样式 | - |
31 changes: 31 additions & 0 deletions src/pages/img/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@
<!-- 以组件位置为定位原点 -->
<wd-img :width="100" :height="100" :src="img" custom-class="border" />
</demo-block>

<demo-block title="插槽用法">
<wd-img :width="100" :height="100" src="https://www.123.com/a.jpg">
<template #error>
<view class="error-wrap">加载失败</view>
</template>
<template #loading>
<view class="loading-wrap">
<wd-loading />
</view>
</template>
</wd-img>
</demo-block>

<demo-block title="填充">
<view class="col" v-for="(mode, index) in modes" :key="index">
<wd-img width="100%" height="27vw" :src="joy" :mode="mode" />
Expand Down Expand Up @@ -78,4 +92,21 @@ const modes: ImageMode[] = [
border: 1px solid red;
margin: 0 10px;
}

.error-wrap {
width: 100%;
height: 100%;
background-color: red;
color: white;
line-height: 100px;
text-align: center;
}

.loading-wrap {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>
18 changes: 16 additions & 2 deletions src/uni_modules/wot-design-uni/components/wd-img/wd-img.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
<template>
<view :class="rootClass" @click="handleClick" :style="rootStyle">
<image :class="`wd-img__image ${customImage}`" :src="src" :mode="mode" :lazy-load="lazyLoad" @load="handleLoad" @error="handleError" />
<image
:class="`wd-img__image ${customImage}`"
:style="status !== 'success' ? 'width: 0;height: 0;' : ''"
:src="src"
:mode="mode"
:lazy-load="lazyLoad"
@load="handleLoad"
@error="handleError"
/>
<slot v-if="status === 'loading'" name="loading"></slot>
<slot v-if="status === 'error'" name="error"></slot>
</view>
</template>
<script lang="ts">
Expand All @@ -15,7 +25,7 @@ export default {
</script>

<script lang="ts" setup>
import { computed } from 'vue'
import { computed, ref } from 'vue'
import { addUnit, isDef, objToStyle } from '../common/util'
import { imgProps } from './types'

Expand All @@ -41,7 +51,10 @@ const rootClass = computed(() => {
return `wd-img ${props.round ? 'is-round' : ''} ${props.customClass}`
})

const status = ref<'loading' | 'error' | 'success'>('loading')

function handleError(event: Event) {
status.value = 'error'
emit('error', event)
}
function handleClick() {
Expand All @@ -53,6 +66,7 @@ function handleClick() {
emit('click')
}
function handleLoad(event: Event) {
status.value = 'success'
emit('load', event)
}
</script>
Expand Down