一、前言
在做一个聊天的输入框,需求是输入框高度自定撑开,到达一定高度后(5行)就不再撑开,高度固定,可以滚动已填写的内容。图如下:
二、方案
传统的思路是 min-height 和 max-height,不过在这里都不适用于 textarea,查看 uniapp 关于 textarea 的介绍,自动撑开可以用 autoHeight 来实现,当autoHeight 启用时,style.height 失效。 那就可以通过判断内容的长度来动态启用 autoHeight。
1. 获取行数
通过 @linechange="handleLineChange" 来获取行数的话,初始状态下会立即调用,获取 event.detail 的内容。
{
height: 22
heightRpx: 38.55140186915888
lineCount: 1
lineHeight: 21.6
}
2. 动态设置 autoHeight
当行数变化时,会触发这个方法。当行数大于等于4时,就关闭 autoHeight,之后 textarea 就不会被撑开。
handleLineChange(e) {
const count = e.detail.lineCount;
this.autoHeight = count >= 4 ? false : true;
},
到这里,正常输入内容就没问题了,在页面上,随着内容的输入,第一行、第二行...都能撑开输入框,最多会显示5行,超过5行后不再撑开,在内部会生成滚动条。
3. 高度固定 !!!
到了上面那步,已经没问题了,但在输入框里粘贴大量内容时,输入框还是会被撑开,也就是说,尽管此时的 autoHeight 已经设置为 false 了,但 textarea 内置的高度并没有生效。尝试了在样式类里设置了高度,也不生效。
因此,可以在行数变化时,显示的设置 textarea 的高度。
:style="{
opacity: isShowVoice ? 0 : 1,
height: `${inputHeight}px`,
}"
!!! 重点来了,根据文档里说的,当 autoHeight 启动时,style.height 不生效,所以我进入了一个误区,我始终把 height 设置为一个值,认为当 aotoHeight 关闭时,高度就会生效,现在看来,这种写法和在样式类里写高度没什么区别 。
handleLineChange(e) {
const count = e.detail.lineCount;
this.autoHeight = count >= 4 ? false : true;
this.inputHeight = 106; // 写死高度
},
以上是不生效的。因此,核心点是: height 必须变化。
handleLineChange(e) {
const count = e.detail.lineCount;
this.autoHeight = count >= 4 ? false : true;
this.inputHeight = count >= 4 ? 106 : 22;
},
这样,在粘贴大量文本时,inputHeight 改变,触发重新渲染,就生效了。
没想到,随手的事,却调试了许久。 不过,如果是用 if-else 来写,我应该不会漏了 this.inputHeight = 22 这种默认的情况。