project init
This commit is contained in:
73
components/image/README.md
Normal file
73
components/image/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Image 图片
|
||||
description: 用于展示效果,主要为上下左右居中裁切、拉伸、平铺等方式。
|
||||
spline: base
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-100%25-blue" /></span>
|
||||
## 引入
|
||||
|
||||
全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-image": "tdesign-miniprogram/image/image"
|
||||
}
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 裁切样式
|
||||
{{ mode }}
|
||||
|
||||
|
||||
### 圆角样式
|
||||
|
||||
{{ shape }}
|
||||
|
||||
### 加载-默认提示
|
||||
|
||||
{{ image-loading }}
|
||||
|
||||
|
||||
### 加载-自定义提示
|
||||
|
||||
{{ custom-loading }}
|
||||
|
||||
### 加载失败-默认提示
|
||||
|
||||
{{ error-loading }}
|
||||
|
||||
### 加载失败-自定义提示
|
||||
|
||||
{{ custom-error-loading }}
|
||||
|
||||
### 常用图片尺寸
|
||||
|
||||
{{ size }}
|
||||
|
||||
|
||||
## API
|
||||
### Image Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
error | String / Slot | 'default' | 加载失败时显示的内容。值为 `default` 则表示使用默认加载失败风格;值为空或者 `slot` 表示使用插槽渲染,插槽名称为 `error`;值为其他则表示普通文本内容,如“加载失败” | N
|
||||
external-classes | Array | - | 组件类名,分别用于设置加载组件外层元素,中间内容等元素类名。`['t-class', 't-class-load']` | N
|
||||
lazy | Boolean | false | 是否开启图片懒加载 | N
|
||||
loading | String / Slot | 'default' | 加载态内容。值为 `default` 则表示使用默认加载中风格;值为空或者 `slot` 表示使用插槽渲染,插槽名称为 `loading`;值为其他则表示普通文本内容,如“加载中” | N
|
||||
shape | String | square | 图片圆角类型。可选项:circle/round/square | N
|
||||
src | String | - | 图片链接 | N
|
||||
mode | String | scaleToFill | 图片裁剪、缩放的模式。<br />具体释义:<br />`scaleToFill` 缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素;<br />`aspectFit` 缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。;<br />`aspectFill` 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。;<br />`widthFix` 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变;<br />`heightFix` 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变;<br />`top` 裁剪模式,不缩放图片,只显示图片的顶部区域;<br />`bottom` 裁剪模式,不缩放图片,只显示图片的底部区域;<br />`center` 裁剪模式,不缩放图片,只显示图片的中间区域;<br />`left` 裁剪模式,不缩放图片,只显示图片的左边区域;<br />`right` 裁剪模式,不缩放图片,只显示图片的右边区域;<br />`top left` 裁剪模式,不缩放图片,只显示图片的左上边区域;<br />`top right` 裁剪模式,不缩放图片,只显示图片的右上边区域;<br />`bottom left` 裁剪模式,不缩放图片,只显示图片的左下边区域;<br />`bottom right` 裁剪模式,不缩放图片,只显示图片的右下边区域。<br />[小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/image.html)。可选项:scaleToFill/aspectFit/aspectFill/widthFix/heightFix/top/bottom/center/left/right/top left/top right/bottom left/bottom right | N
|
||||
webp | Boolean | false | 默认不解析 webP 格式,只支持网络资源 | N
|
||||
show-menu-by-longpress | Boolean | false | 长按图片显示发送给朋友、收藏、保存图片、搜一搜、打开名片/前往群聊/打开小程序(若图片中包含对应二维码或小程序码)的菜单。 | N
|
||||
binderror | Eventhandle | - | 当错误发生时触发,event.detail = {errMsg} | N
|
||||
bindload | Eventhandle | - | 当图片载入完毕时触发,event.detail = {height, width} | N
|
||||
|
||||
### Image Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
error | - | 图片加载失败时触发
|
||||
load | - | 图片加载完成时触发
|
||||
75
components/image/image-info.json
Normal file
75
components/image/image-info.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"key": "Image",
|
||||
"label": "图片",
|
||||
"icon": "",
|
||||
"properties": [
|
||||
{
|
||||
"key": "error",
|
||||
"type": ["String", "TNode"],
|
||||
"defaultValue": "'default'",
|
||||
"desc": "加载失败时显示的内容。值为 `default` 则表示使用默认加载失败风格;值为空或者 `slot` 表示使用插槽渲染,插槽名称为 `error`;值为其他则表示普通文本内容,如“加载失败”",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"key": "externalClasses",
|
||||
"type": ["Array"],
|
||||
"defaultValue": "",
|
||||
"desc": "组件类名,分别用于设置加载组件外层元素,中间内容等元素类名",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"key": "lazy",
|
||||
"type": ["Boolean"],
|
||||
"defaultValue": "false",
|
||||
"desc": "是否开启图片懒加载",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"key": "loading",
|
||||
"type": ["String", "TNode"],
|
||||
"defaultValue": "'default'",
|
||||
"desc": "加载态内容。值为 `default` 则表示使用默认加载中风格;值为空或者 `slot` 表示使用插槽渲染,插槽名称为 `loading`;值为其他则表示普通文本内容,如“加载中”",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"key": "MP_EXCLUDE_PROPS",
|
||||
"type": ["String"],
|
||||
"defaultValue": "",
|
||||
"desc": "为避免重复或冲突,需要过滤掉的小程序原生属性",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"key": "MP_PROPS",
|
||||
"type": ["String"],
|
||||
"defaultValue": "",
|
||||
"desc": "[小程序原生属性](https://developers.weixin.qq.com/miniprogram/dev/component/image.html)",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"key": "shape",
|
||||
"type": ["String"],
|
||||
"defaultValue": "square",
|
||||
"desc": "图片圆角类型",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"key": "src",
|
||||
"type": ["String"],
|
||||
"defaultValue": "",
|
||||
"desc": "图片链接",
|
||||
"label": ""
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"key": "error",
|
||||
"desc": "图片加载失败时触发",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"key": "load",
|
||||
"desc": "图片加载完成时触发",
|
||||
"label": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
27
components/image/image.d.ts
vendored
Normal file
27
components/image/image.d.ts
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { SuperComponent } from '../common/src/index';
|
||||
export default class Image extends SuperComponent {
|
||||
externalClasses: string[];
|
||||
options: {
|
||||
multipleSlots: boolean;
|
||||
};
|
||||
properties: import("./type").TdImageProps;
|
||||
data: {
|
||||
prefix: string;
|
||||
isLoading: boolean;
|
||||
isFailed: boolean;
|
||||
widthStyle: string;
|
||||
classPrefix: string;
|
||||
};
|
||||
preSrc: string;
|
||||
lifetimes: {
|
||||
attached(this: Image): void;
|
||||
};
|
||||
observers: {
|
||||
src(): void;
|
||||
};
|
||||
methods: {
|
||||
onLoaded(e: any): void;
|
||||
onLoadError(e: any): void;
|
||||
update(): void;
|
||||
};
|
||||
}
|
||||
92
components/image/image.js
Normal file
92
components/image/image.js
Normal file
@@ -0,0 +1,92 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
import { SuperComponent, wxComponent } from '../common/src/index';
|
||||
import ImageProps from './props';
|
||||
import config from '../common/config';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-image`;
|
||||
let Image = class Image extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.externalClasses = ['t-class', 't-class-load'];
|
||||
this.options = {
|
||||
multipleSlots: true,
|
||||
};
|
||||
this.properties = ImageProps;
|
||||
this.data = {
|
||||
prefix,
|
||||
isLoading: true,
|
||||
isFailed: false,
|
||||
widthStyle: '',
|
||||
classPrefix: name,
|
||||
};
|
||||
this.preSrc = '';
|
||||
this.lifetimes = {
|
||||
attached() {
|
||||
this.update();
|
||||
},
|
||||
};
|
||||
this.observers = {
|
||||
src() {
|
||||
if (this.preSrc === this.properties.src)
|
||||
return;
|
||||
this.update();
|
||||
},
|
||||
};
|
||||
this.methods = {
|
||||
onLoaded(e) {
|
||||
const sdkVersion = wx.getSystemInfoSync().SDKVersion;
|
||||
const versionArray = sdkVersion.split('.').map((v) => parseInt(v, 10));
|
||||
const { mode } = this.properties;
|
||||
const isInCompatible = versionArray[0] < 2 ||
|
||||
(versionArray[0] === 2 && versionArray[1] < 10) ||
|
||||
(versionArray[0] === 2 && versionArray[1] === 10 && versionArray[2] < 3);
|
||||
if (mode === 'heightFix' && isInCompatible) {
|
||||
const { height: picHeight, width: picWidth } = e.detail;
|
||||
const query = this.createSelectorQuery();
|
||||
query
|
||||
.select('#image')
|
||||
.boundingClientRect((res) => {
|
||||
const { height } = res;
|
||||
const resultWidth = ((height / picHeight) * picWidth).toFixed(2);
|
||||
this.setData({ widthStyle: `width: ${resultWidth}px;` });
|
||||
})
|
||||
.exec();
|
||||
}
|
||||
this.setData({
|
||||
isLoading: false,
|
||||
isFailed: false,
|
||||
});
|
||||
this.triggerEvent('load', e.detail);
|
||||
},
|
||||
onLoadError(e) {
|
||||
this.setData({
|
||||
isLoading: false,
|
||||
isFailed: true,
|
||||
});
|
||||
this.triggerEvent('error', e.detail);
|
||||
},
|
||||
update() {
|
||||
const { src } = this.properties;
|
||||
this.preSrc = src;
|
||||
if (!src) {
|
||||
this.onLoadError({ errMsg: '图片链接为空' });
|
||||
}
|
||||
else {
|
||||
this.setData({
|
||||
isLoading: true,
|
||||
isFailed: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
Image = __decorate([
|
||||
wxComponent()
|
||||
], Image);
|
||||
export default Image;
|
||||
6
components/image/image.json
Normal file
6
components/image/image.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"t-icon": "../icon/icon"
|
||||
}
|
||||
}
|
||||
45
components/image/image.wxml
Normal file
45
components/image/image.wxml
Normal file
@@ -0,0 +1,45 @@
|
||||
<!-- 加载中占位 -->
|
||||
<view
|
||||
wx:if="{{isLoading}}"
|
||||
class="{{prefix}}-class {{classPrefix}} {{classPrefix}}__mask {{classPrefix}}--loading {{classPrefix}}--shape-{{shape}}"
|
||||
>
|
||||
<t-loading
|
||||
wx:if="{{loading === 'default'}}"
|
||||
theme="dots"
|
||||
size="40rpx"
|
||||
loading
|
||||
class="t-class-load"
|
||||
t-class-text="{{classPrefix}}--loading-text"
|
||||
></t-loading>
|
||||
<view wx:elif="{{loading !== 'slot' && loading !== ''}}" class="{{classPrefix}}__common {{prefix}}-class-load">
|
||||
{{loading}}
|
||||
</view>
|
||||
<slot wx:else name="loading" class="{{prefix}}-class-load" />
|
||||
</view>
|
||||
<!-- 加载失败占位 -->
|
||||
<view
|
||||
wx:elif="{{isFailed}}"
|
||||
class="{{prefix}}-class {{classPrefix}} {{classPrefix}}__mask {{classPrefix}}--faild {{classPrefix}}--shape-{{shape}}"
|
||||
>
|
||||
<view wx:if="{{error === 'default'}}" style="font-size: 40rpx; color: #999" class="{{prefix}}-class-load">
|
||||
<t-icon name="close" />
|
||||
</view>
|
||||
<view wx:elif="{{error !== 'slot' && error !== ''}}" class="{{classPrefix}}__common {{prefix}}-class-load">
|
||||
{{error}}
|
||||
</view>
|
||||
<slot wx:else name="error" class="{{prefix}}-class-load"></slot>
|
||||
</view>
|
||||
<!-- 图片 -->
|
||||
<image
|
||||
id="image"
|
||||
hidden="{{isLoading || isFailed}}"
|
||||
class="{{prefix}}-class {{classPrefix}} {{classPrefix}}--shape-{{shape}}"
|
||||
src="{{src}}"
|
||||
style="{{widthStyle}}"
|
||||
mode="{{mode}}"
|
||||
webp="{{webp}}"
|
||||
lazy-load="{{lazy}}"
|
||||
bind:load="onLoaded"
|
||||
bind:error="onLoadError"
|
||||
show-menu-by-longpress="{{showMenuByLongpress}}"
|
||||
/>
|
||||
54
components/image/image.wxss
Normal file
54
components/image/image.wxss
Normal file
@@ -0,0 +1,54 @@
|
||||
.t-float-left {
|
||||
float: left;
|
||||
}
|
||||
.t-float-right {
|
||||
float: right;
|
||||
}
|
||||
@keyframes tdesign-fade-out {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.hotspot-expanded.relative {
|
||||
position: relative;
|
||||
}
|
||||
.hotspot-expanded::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
transform: scale(1.5);
|
||||
}
|
||||
.t-image__mask {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #f2f2f2;
|
||||
color: #ccc;
|
||||
}
|
||||
.t-image--loading-text {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
.t-image__common {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.t-image--shape-circle {
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-image--shape-round {
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-image--shape-square {
|
||||
border-radius: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
4
components/image/index.d.ts
vendored
Normal file
4
components/image/index.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { TdImageProps } from './type';
|
||||
export declare type ImageProps = TdImageProps;
|
||||
export * from './props';
|
||||
export * from './image';
|
||||
2
components/image/index.js
Normal file
2
components/image/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './props';
|
||||
export * from './image';
|
||||
3
components/image/props.d.ts
vendored
Normal file
3
components/image/props.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { TdImageProps } from './type';
|
||||
declare const props: TdImageProps;
|
||||
export default props;
|
||||
38
components/image/props.js
Normal file
38
components/image/props.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const props = {
|
||||
error: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
},
|
||||
externalClasses: {
|
||||
type: Array,
|
||||
},
|
||||
lazy: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
loading: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
},
|
||||
shape: {
|
||||
type: String,
|
||||
value: 'square',
|
||||
},
|
||||
src: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
value: 'scaleToFill',
|
||||
},
|
||||
webp: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
showMenuByLongpress: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
38
components/image/type.d.ts
vendored
Normal file
38
components/image/type.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
export interface TdImageProps {
|
||||
error?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
externalClasses?: {
|
||||
type: ArrayConstructor;
|
||||
value?: ['t-class', 't-class-load'];
|
||||
};
|
||||
lazy?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
loading?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
shape?: {
|
||||
type: StringConstructor;
|
||||
value?: 'circle' | 'round' | 'square';
|
||||
};
|
||||
src?: {
|
||||
type: StringConstructor;
|
||||
value?: string;
|
||||
};
|
||||
mode?: {
|
||||
type: StringConstructor;
|
||||
value?: 'scaleToFill' | 'aspectFit' | 'aspectFill' | 'widthFix' | 'heightFix' | 'top' | 'bottom' | 'center' | 'left' | 'right' | 'top left' | 'top right' | 'bottom left' | 'bottom right';
|
||||
};
|
||||
webp?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
showMenuByLongpress?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
}
|
||||
1
components/image/type.js
Normal file
1
components/image/type.js
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Reference in New Issue
Block a user