☰
微信小程序 t-image 图片组件详解:TDesign 组件库裁切模式、加载状态与完整 API 实战指南
2026/10/15 15:21:57 网站建设 项目流程
  • 示例工程
  • 小程序
  • 前端

【免费下载链接】miniprogram-demo

微信小程序组件 / API / 云开发示例

项目地址:https://gitcode.com/gh_mirrors/mi/miniprogram-demo
点击查看免费下载

导读

本文以 miniprogram-demo 开源示例项目中内置的 TDesign 微信小程序组件库tdesign-miniprogram/image图片组件为核心,系统讲解t-image的引入方式、裁切模式(mode)、圆角形状(shape)、加载态与错误态定制、懒加载与 WebP 支持,以及底层源码实现原理。读者读完本文后,可以在自己的微信小程序页面中快速接入并灵活配置t-image,实现居中裁切、等比缩放、圆角头像、自定义加载失败占位等常见图片展示需求,并能理解其源码内部的加载状态机与尺寸计算逻辑。

该组件位于仓库 miniprogram/packageAPI/components/tdesign-miniprogram/image,本示例项目(微信小程序组件 / API / 云开发示例)的多个页面与组件(如 activity_create/index.wxml、cell、empty等)都在实际复用该图片组件。

一、组件定位与适用场景

t-image是对微信小程序原生<image>组件的封装与增强,官方描述为"用于展示效果,主要为上下左右居中裁切、拉伸、平铺等方式"。它继承了小程序原生 image 的裁切缩放能力,并额外提供了:

  • 统一的加载中 / 加载失败占位态(默认样式或插槽自定义);
  • 三种圆角形状(圆形 / 圆角 / 方形);
  • 懒加载、WebP 解析、长按菜单等原生能力透传;
  • 通过外部样式类(external classes)与 CSS 变量进行主题定制。

从源码结构看,组件继承自SuperComponent(见 image.js),内部维护isLoading、isFailed两个状态,配合<t-loading>加载动画组件与<t-icon>错误图标组件渲染占位内容,是一个典型的"状态机 + 原生能力透传"型封装组件。

二、组件引入方式

与所有 TDesign 小程序组件一致,t-image支持全局引入与局部引入两种方式。

全局引入

在miniprogram根目录下的app.json的usingComponents字段中声明:

"usingComponents": { "t-image": "tdesign-miniprogram/image/image" }

局部引入

在需要使用的页面或组件对应的index.json中声明,路径需要相对该 json 文件计算。以本仓库为例,activity_create/index.json 中按相对路径引入:

{ "usingComponents": { "t-image": "../../components/tdesign-miniprogram/image/image" } }

引入后即可在 WXML 中直接使用:

<t-image src="{{shareImage}}" mode="aspectFill" width="48" height="48" />

Tips:若使用官方开发者工具预览本示例,请确保开发者工具为打开状态;导入项目后依次执行:npm i> 构建 npm 包 > 勾选"将 JS 编译成 ES5"。

三、裁切样式(mode)详解

t-image的mode属性完全透传给原生<image>组件,决定图片的裁剪与缩放方式,默认值为scaleToFill。可选项与语义如下:

| mode 值 | 效果说明 | | -- | -- | |scaleToFill| 默认值。拉伸填满容器,不保持宽高比,可能变形 | |aspectFit| 保持宽高比缩放,完整显示图片,可能有留白 | |aspectFill| 保持宽高比缩放并裁切,填满容器,可能裁掉部分图片 | |widthFix| 宽度不变,高度自动变化,保持宽高比 | |heightFix| 高度不变,宽度自动变化,保持宽高比 | |top/bottom/center/left/right| 不缩放,按对应方向对齐显示 | |top left/top right/bottom left/bottom right| 不缩放,按四个角对齐显示 |

实战建议

  • 头像、封面图等需要"铺满且居中裁切"的场景,使用aspectFill;
  • 需要"完整展示整张图"(如商品主图)的场景,使用aspectFit;
  • 需要"宽度固定、高度自适应"的图文列表场景,使用widthFix;
  • 需要注意,scaleToFill会拉伸变形,一般用于明确知道原始比例的图片。

源码对 heightFix 的兼容处理

从源码看(image.js),组件对mode === 'heightFix'在低版本基础库下做了特殊兜底:通过compareVersion(sdkVersion, '2.10.3')判断基础库版本,若低于2.10.3,则在图片load事件中通过getRect(this, '#image')读取节点实际高度,并按照原始宽高比计算展示宽度,写入innerStyle。这保证了heightFix模式在旧版本微信上的显示一致性。版本比较逻辑见 common/version.js。

四、尺寸设置与单位处理

t-image提供width与height两个属性用于控制图片显示尺寸,类型为String / Number,默认值为-(不限制,由内容或父容器决定)。

  • 传入纯数字(如48)时,默认单位按px处理;
  • 传入带单位字符串(如"100rpx")时,原样使用。

源码中calcSize方法(image.js)监听width, height两个属性的变化,通过addUnit工具(common/utils.js)统一追加px单位:纯数字会被转换成${value}px,带单位的字符串则直接透传。生成的样式通过innerStyle同时作用于占位层与图片节点,保证加载占位与图片本体尺寸一致。

五、加载状态与失败状态定制

t-image内部维护isLoading与isFailed两个布尔状态(见 image.js),并根据状态渲染三层结构(见 image.wxml):

  1. 加载中占位层(isLoading为 true);
  2. 加载失败占位层(isFailed为 true);
  3. 图片本体(!isFailed时渲染)。

loading 属性

loading属性控制加载中的占位内容,类型为String / Slot,默认值'default':

| 取值 | 行为 | | -- | -- | |'default'| 使用默认加载风格,即内置的<t-loading>圆点加载动画(theme="dots"、size="44rpx") | | 空字符串或'slot'| 使用插槽渲染,插槽名称为loading| | 其他字符串 | 作为普通文本直接显示,如loading="加载中"|

error 属性

error属性控制加载失败时的占位内容,类型为String / Slot,默认值'default':

| 取值 | 行为 | | -- | -- | |'default'| 使用默认加载失败风格,即内置的<t-icon name="close">关闭图标 | | 空字符串或'slot'| 使用插槽渲染,插槽名称为error| | 其他字符串 | 作为普通文本直接显示,如error="加载失败"|

组件在image.json中声明了"multipleSlots": true(见 image.json),支持多插槽渲染。

插槽自定义示例

<t-image src="{{imgUrl}}"> <!-- 自定义加载中内容 --> <view slot="loading">图片加载中…</view> <!-- 自定义加载失败内容 --> <view slot="error">图片走丢了</view> </t-image>

加载状态机源码解析

src属性的 observer(image.js)会先对比preSrc,仅在图片地址真正变化时调用update():

  • 若src为空,直接进入失败态并触发error事件(errMsg为"图片链接为空");
  • 否则重置为"加载中"状态,交由原生<image>的load/error事件推进状态。

onLoaded在图片加载完成后将isLoading置为 false、isFailed置为 false,并向上触发load事件;onLoadError则将isLoading置为 false、isFailed置为 true,并向上触发error事件(见 image.js)。此外 WXML 中还透传了aria-hidden与aria-label,在加载中 / 失败 / 图片展示阶段合理控制无障碍语义,提升辅助功能体验。

六、形状(shape)与圆角

shape属性控制图片圆角类型,类型为String,默认值square,可选项:

| 取值 | 效果 | 底层实现(见 image.wxss) | | -- | -- | -- | |circle| 圆形,适用于头像 |border-radius: 50%; overflow: hidden;| |round| 圆角矩形,圆角值由 CSS 变量控制 |border-radius: var(--td-image-round-radius, var(--td-radius-default, 12rpx)); overflow: hidden;| |square| 直角矩形 |border-radius: 0; overflow: hidden;|

该形状样式同时应用于占位层与图片本体,因此加载中、失败态的占位块与图片共享相同的圆角外观。

七、原生能力透传:懒加载、WebP 与长按菜单

以下属性由t-image直接透传给原生<image>组件(见 image.wxml):

  • lazy(Boolean,默认false):是否开启图片懒加载,对应原生lazy-load属性。开启后,图片进入视口附近时才加载,适合长列表场景,能有效减少网络请求。从源码看(image.js),懒加载开启时会给图片节点追加--lazy类名,其样式将图片绝对定位并置于z-index: -1(见 image.wxss),确保懒加载过程中的占位层正常展示;
  • webp(Boolean,默认false):是否解析 WebP 格式。默认不解析,且该能力只支持网络资源,本地图片无效;
  • show-menu-by-longpress(Boolean,默认false):长按图片时显示系统菜单(发送给朋友、收藏、保存图片、搜一搜、识别二维码/小程序码等)。

示例:

<t-image src="{{imgUrl}}" lazy webp show-menu-by-longpress mode="aspectFill" />

八、事件

t-image对外暴露两个事件:

| 事件名 | 触发时机 | | -- | -- | |load| 图片加载完成时触发,事件对象携带原生 detail 数据(图片宽高等) | |error| 图片加载失败时触发(包括src为空的情况) |

监听方式(在onLoaded源码中通过this.triggerEvent('load', e.detail)触发,见 image.js):

<t-image src="{{imgUrl}}" bind:load="onImgLoad" bind:error="onImgError" />
Page({ onImgLoad(e) { console.log('图片加载完成', e.detail); }, onImgError(e) { console.log('图片加载失败', e.detail); }, });

九、常见问题:本地图片无法正确引用

官方文档给出的排查结论:建议使用绝对路径,而不是相对路径。小程序中绝对路径以app.json所在位置为基准。

例如app.json位于miniprogram/根目录时,引用本地图片可写为:

<t-image src="/image/icon_API.png" mode="aspectFit" />

相对路径容易因页面层级嵌套(分包、多级目录)而计算错误,统一使用以app.json为基准的绝对路径最稳妥。此外,需确认图片文件确实已上传到代码包内、路径大小写与文件名完全一致。

十、外部样式类(External Classes)

t-image提供 4 个外部样式类,用于在不侵入组件内部的情况下定制各区块样式。从源码看(image.js),这些类声明于externalClasses数组中,前缀取自统一配置prefix(即t):

| 类名 | 作用对象 | | -- | -- | |t-class| 根节点样式类 | |t-class-load| 加载样式类(加载中占位及加载失败占位通用) | |t-class-image| 图片本体样式类 | |t-class-error| 加载失败样式类 |

使用示例:

<t-image src="{{imgUrl}}" t-class="my-img" t-class-load="my-img-load" t-class-image="my-img-body" t-class-error="my-img-error" />
/* 页面 wxss */ .my-img { border: 2rpx solid #eee; } .my-img-body { border-radius: 8rpx; }

同时组件在image.json中配置了"styleIsolation": "apply-shared",页面样式可作用于组件内部,配合外部样式类可实现灵活的局部定制。

十一、CSS 变量定制

组件提供了 4 个 CSS 变量,用于在不改动源码的情况下自定义主题样式:

| CSS 变量 | 默认值 | 说明 | | -- | -- | -- | |--td-image-color|@font-gray-3(文本占位灰色) | 图片区域文字/图标颜色 | |--td-image-loading-bg-color|@bg-color-secondarycontainer(浅灰) | 加载占位背景色 | |--td-image-loading-color|@font-gray-3| 加载占位内容颜色 | |--td-image-round-radius|@radius-default(12rpx) |shape="round"时的圆角半径 |

这些变量在 image.wxss 中均带有三层回退(var(--td-image-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))))形式),即组件变量 → 全局 TDesign 变量 → 内置硬编码默认值,三层兜底保证了任何主题下都有可用样式。可在页面或全局 wxss 中覆盖:

page { --td-image-loading-bg-color: #f5f5f5; --td-image-round-radius: 16rpx; --td-image-loading-color: #999999; }

十二、项目中的真实使用示例

1. 自定义分享图缩略展示

在 activity_create/index.wxml 中,创建活动页使用t-image展示用户选择的分享图,aspectFill模式保证 48px 见方的缩略图铺满且居中裁切:

<t-cell bind:tap="chooseShareImage" title="自定义分享图" hover> <view slot="note"> <t-icon wx:if="{{!shareImage}}" name="image-add" size="48rpx" /> <t-image wx:else src="{{shareImage}}" mode="aspectFill" width="48" height="48" /> </view> </t-cell>

2. 其他 TDesign 组件的内部复用

t-image同时也是本仓库其他组件的内部依赖:

  • cell组件通过t-image渲染左侧图片(cell.json);
  • empty组件通过t-image渲染空状态插图(mode="aspectFit",见 empty.wxml);
  • 通用模板 common/template/image.wxml 将t-image的所有属性、事件封装为可复用 template,供业务侧按需传入。

这印证了t-image作为基础图片组件的高复用性:它既可直接服务于业务页面,也可作为上层组件的内部构件。

十三、完整 Props 速查表

综合 props.js 与 type.d.ts 的类型定义,t-image的完整属性如下:

| 名称 | 类型 | 默认值 | 描述 | 必传 | | -- | -- | -- | -- | -- | | style | Object | - | 样式 | N | | custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N | | error | String / Slot |'default'| 加载失败时显示的内容。default表示默认失败风格;空值或slot表示使用error插槽渲染;其他值为普通文本(如"加载失败") | N | | height | String / Number | - | 高度,默认单位为px| N | | lazy | Boolean |false| 是否开启图片懒加载 | N | | loading | String / Slot |'default'| 加载态内容。default表示默认加载中风格;空值或slot表示使用loading插槽渲染;其他值为普通文本(如"加载中") | N | | mode | String |scaleToFill| 图片裁剪、缩放模式。可选项:scaleToFill/aspectFit/aspectFill/widthFix/heightFix/top/bottom/center/left/right/top left/top right/bottom left/bottom right| N | | shape | String |square| 图片圆角类型。可选项:circle/round/square| N | | show-menu-by-longpress | Boolean |false| 长按图片显示发送给朋友、收藏、保存图片、搜一搜、打开名片/前往群聊/打开小程序的菜单 | N | | src | String | - | 图片链接 | N | | t-id | String | - | 图片标签 id(用于节点查询定位) | N | | webp | Boolean |false| 是否解析 WebP 格式,默认不解析,只支持网络资源 | N | | width | String / Number | - | 宽度,默认单位为px| N |

十四、相关文件索引

如需深入阅读组件实现与配套工具,可查看以下仓库文件:

  • 组件入口与状态机:miniprogram/packageAPI/components/tdesign-miniprogram/image/image.js
  • 属性声明:miniprogram/packageAPI/components/tdesign-miniprogram/image/props.js
  • 组件模板:miniprogram/packageAPI/components/tdesign-miniprogram/image/image.wxml
  • 组件样式与 CSS 变量:miniprogram/packageAPI/components/tdesign-miniprogram/image/image.wxss
  • TypeScript 类型定义:miniprogram/packageAPI/components/tdesign-miniprogram/image/type.d.ts
  • 组件信息元数据(API 文档数据源):miniprogram/packageAPI/components/tdesign-miniprogram/image/image-info.json
  • 通用工具(尺寸单位、节点查询):miniprogram/packageAPI/components/tdesign-miniprogram/common/utils.js
  • 版本比较工具:miniprogram/packageAPI/components/tdesign-miniprogram/common/version.js

结语

t-image以极小的心智负担覆盖了微信小程序图片展示的大部分典型需求:裁切缩放、圆角形状、加载/失败占位、懒加载、WebP、长按菜单与无障碍支持一应俱全,且通过外部样式类和 CSS 变量提供了充分的定制空间。理解其"状态机 + 原生能力透传 + 主题变量三层回退"的源码设计,不仅能帮助你在使用中精准定位问题,也能为封装其他基础组件提供良好的参考范式。

  • 示例工程
  • 小程序
  • 前端

【免费下载链接】miniprogram-demo

微信小程序组件 / API / 云开发示例

项目地址:https://gitcode.com/gh_mirrors/mi/miniprogram-demo
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询