ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

TDesign Textarea 占位符字号问题修复解析:placeholder 样式的实现机制与自定义指南

TDesign Textarea 占位符字号问题修复解析:placeholder 样式的实现机制与自定义指南
  • 前端
  • UI组件
  • 小程序
  • 设计系统
  • 移动开发

【免费下载链接】tdesign-miniprogram

Wechat MiniProgram and Uniapp UI components lib for TDesign

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

本文基于 tdesign-miniprogram 仓库中 pr-4661 变更记录 展开,围绕 TDesign 多行输入框(Textarea)组件placeholder占位内容字号的一次修复,从变更记录出发,深入到小程序与 Uniapp 两端组件的源码实现,梳理占位符的渲染链路、字号与颜色样式的定义位置,并给出在页面中自定义占位符样式的完整方案。读完本文,你将掌握 TDesign Textarea 占位符样式的底层实现与三类覆盖方式,能够独立排查和定制placeholder的字号与颜色。

一、变更记录:一次聚焦 placeholder 字号的修复

在packages/tdesign-uniapp/.changelog/pr-4661.md中记录了这样一条变更:

fix(Textarea): 修复 `placeholder` 占位内容字号错误 @anlyyao (#4661)

这条记录的格式遵循仓库 changelog 文件的规范结构:文件头部包含pr_number(4661)与contributor(anlyyao)两项元数据,正文为一条精简的修复说明。fix(Textarea)表明本次修改作用于 Textarea 组件,问题现象是placeholder占位内容的字号不正确,修复目标就是让占位内容在视觉上恢复正确的字号表现。

这类碎片化记录由仓库的 changelog 机制统一收集,并汇总进各包根目录的CHANGELOG.md(例如 packages/tdesign-uniapp/CHANGELOG.md),仓库根目录下还有 script/generate-changelog.js 等脚本参与 changelog 的生成维护。要真正理解这次修复"修了什么、为什么这样修",需要回到 Textarea 组件源码,把 placeholder 从属性声明到渲染、再到样式命名的整条链路走一遍。

二、placeholder 的渲染链路:属性是如何传递到原生 textarea 的

Textarea 组件最终渲染的是微信小程序 / Uniapp 的原生<textarea>节点,因此 placeholder 相关属性必须透传到原生组件上。以小程序版 textarea.wxml 为例,核心透传代码如下:

<textarea class="{{classPrefix}}__wrapper-inner {{disabled? prefix + '-is-disabled' : ''}} {{prefix}}-class-textarea" maxlength="{{allowInputOverMax ? -1 : maxlength}}" disabled="{{disabled || readonly}}" placeholder="{{placeholder}}" placeholder-class="{{classPrefix}}__placeholder {{placeholderClass}}" placeholder-style="{{placeholderStyle}}" value="{{value}}" ... />

其中三个占位符相关属性分别承担不同职责:

  • placeholder:占位内容文本,直接绑定组件属性;
  • placeholder-class:占位符样式类,这里是组件内部类t-textarea__placeholder与用户传入的placeholderClass拼接,意味着内部样式和外部自定义类会同时生效;
  • placeholder-style:占位符内联样式,优先级最高,用于临时覆盖。

Uniapp 版的 textarea.vue 与小程序版结构完全对齐,同样透传这三个属性:

<textarea :placeholder="placeholder" :placeholder-class="classPrefix + '__placeholder ' + placeholderClass" :placeholder-style="placeholderStyle" ... />

这构成了理解本次字号修复的第一层背景:占位符的字号由placeholder-class指向的样式类决定,修复点必然落在该样式类对应的样式定义上。

三、字号样式的落点:内部类与 Less 变量的定义

组件属性声明在 props.ts 中,三个相关属性的默认值如下:

| 属性 | 类型 | 默认值 | 说明 | | -- | -- | -- | -- | | placeholder | String | undefined | 占位符文本 | | placeholder-class | String |textarea-placeholder| 指定 placeholder 的样式类,目前仅支持 color、font-size 和 font-weight | | placeholder-style | String |''| 指定 placeholder 的样式,目前仅支持 color、font-size 和 font-weight |

需要注意:属性层面placeholder-class的默认值是textarea-placeholder,而在 WXML 渲染时组件会自动拼接前缀t-textarea__placeholder(即classPrefix + '__placeholder')。真正决定占位符字号的,正是这个内部类t-textarea__placeholder的样式,其定义位于 textarea.less:

@textarea-text-font: @font-body-large; // 输入框文本大小 @textarea-placeholder-font: @font-body-large; // 占位符文本大小 &__placeholder { color: @textarea-placeholder-color; font: @textarea-placeholder-font; }

从当前源码可以看出:

  • 占位符文本字号通过 Less 变量@textarea-placeholder-font定义,取值与输入框文本字号一致,均为设计令牌@font-body-large(即正文大字号);
  • 占位符颜色通过@textarea-placeholder-color定义,对外暴露为 CSS 变量--td-textarea-placeholder-color,默认回落到@text-color-placeholder。

Uniapp 版 textarea.less 中同样存在@textarea-placeholder-font: @font-body-large;与&__placeholder的字号/颜色定义,两端实现保持一致。

从仓库现有的源码与变更记录出发,可以推断:本次 pr-4661 修复针对的正是"占位符字号与输入框正文不匹配"这一类样式偏差,修复后的状态即上文所展示的——placeholder字号统一为@font-body-large,与输入内容字号保持视觉一致。至于修复前的具体字号取值,当前仓库中已无法还原,本文不作推测。

四、为什么占位符字号容易被"修错":样式隔离与覆盖优先级

理解这次修复,还需要知道占位符样式在真实项目中的三个覆盖层,它们决定了"字号错误"出现的常见路径:

  1. 内部类层:t-textarea__placeholder由组件 Less 定义,是默认表现;
  2. 自定义类层:用户通过placeholderClass传入自定义类,与内部类拼接后同时作用于原生节点,双方以 CSS 优先级(权重)决出胜负;
  3. 内联样式层:placeholderStyle以内联 style 注入,优先级最高。

组件官方文档(小程序版 README)为此专门给出提示:

如果需要在页面中调整textarea中placeholder样式,请使用名称为t-textarea__placeholder的 Class 选择器,直接覆盖组件内部样式(注意权重)。

也就是说,只要页面中以足够权重覆盖了t-textarea__placeholder的font-size,就可能在视觉上覆盖组件默认字号,从而出现"占位符字号看起来不对"的结果;反过来,组件自身的font定义若被页面全局样式(如textarea节点的 reset 样式)影响,也可能产生字号偏差。源码中的这些设定(内部类名、拼接逻辑、Less 变量、权重提示)共同构成了本次修复的技术背景。

五、在页面中自定义 placeholder 字号的三种方式

结合上面的机制,实际开发中调整占位符字号有以下三种可靠途径:

方式一:placeholder-class 自定义类

<t-textarea placeholder="请输入多行内容" placeholder-class="my-placeholder" />

页面样式(注意权重高于组件内部定义):

.my-placeholder { font-size: 28rpx; }

方式二:placeholder-style 内联样式

<t-textarea placeholder="请输入多行内容" placeholder-style="color: #999999; font-size: 28rpx; font-weight: 400;" />

方式三:组件外部类 / CSS 变量

  • 外部类:t-class-textarea(多行文本框样式类)、t-class-label(左侧文本样式类)、t-class-indicator(计数器样式类)、t-class(根节点样式类),其中占位符直接作用于输入框内,可结合t-class-textarea联动处理;
  • CSS 变量:占位符颜色可通过--td-textarea-placeholder-color覆盖(默认@text-color-placeholder),如下:
page { --td-textarea-placeholder-color: #bbbbbb; }

三种方式的优先级从低到高为:外部类 / CSS 变量 → placeholder-class → placeholder-style,实际落地时按需求选择,并始终注意内部类t-textarea__placeholder的权重约束。

六、跨平台实现对照与辅助机制

本次修复发生在 Uniapp 包(packages/tdesign-uniapp),但修复对象的实现同时存在于小程序与 Uniapp 两端,对应关系如下:

| 维度 | 小程序版 | Uniapp 版 | | -- | -- | -- | | 组件主文件 | textarea.ts | textarea.vue | | 属性定义 | props.ts | props.ts | | 类型定义 | type.ts | type.ts | | 样式 | textarea.less | textarea.less | | 自动增高逻辑 | wxs:textarea.wxs | computed.js |

两端在占位符透传与内部类命名上完全一致(均拼接classPrefix + '__placeholder');差异主要在于框架语法:Uniapp 版使用 Vue 的:placeholder绑定并支持v-model:value(见其emits: ['update:value']与emitChange方法),小程序版使用 WXML 绑定与triggerEvent事件透传。本次"placeholder 占位内容字号错误"的修复点在两端共享的 Less 层,因此修复思路对两端同时适用。

七、测试与示例:验证 placeholder 相关行为

仓库为 Textarea 提供了完整的测试与示例,可作为理解与验证的参考:

  • 单元测试:index.test.js 覆盖了style/customStyle、label、maxcharacter、allowInputOverMax、事件(line-change、focus、blur、enter)等行为;快照文件(__snapshots__/index.test.js.snap、demo.test.js.snap)记录了渲染结果的基线;
  • 示例代码:示例目录 中包含base、label、custom、disabled、autosize、maxlength、maxcharacter、card等场景;其中base示例展示了最基础的占位符用法,maxcharacter示例使用占位文案提示"一个汉字表示两个字符";
  • 类型契约:占位符相关属性在 type.ts 中有完整注释,例如placeholderClass注明"目前仅支持 color、font-size 和 font-weight"。

八、小结

pr-4661 记录的placeholder字号修复,表面是一条一行 changelog,背后则牵动着一整套占位符样式机制:属性在 textarea.wxml / textarea.vue 中的透传、内部类t-textarea__placeholder与自定义类的拼接、Less 变量@textarea-placeholder-font的字号定义,以及--td-textarea-placeholder-color的颜色兜底。日常开发中若再遇到占位符字号不符预期,可按"先确认placeholder-class/placeholder-style是否覆盖,再检查页面全局样式权重,最后核对t-textarea__placeholder内部定义"的顺序排查;两端(小程序与 Uniapp)的实现保持一致,修复经验可互通复用。

  • 前端
  • UI组件
  • 小程序
  • 设计系统
  • 移动开发

【免费下载链接】tdesign-miniprogram

Wechat MiniProgram and Uniapp UI components lib for TDesign

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

相关推荐

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进