uniapp - textarea 高度 踩坑

639 阅读2分钟

一、前言

在做一个聊天的输入框,需求是输入框高度自定撑开,到达一定高度后(5行)就不再撑开,高度固定,可以滚动已填写的内容。图如下:

image.png

二、方案

传统的思路是 min-heightmax-height,不过在这里都不适用于 textarea,查看 uniapp 关于 textarea 的介绍,自动撑开可以用 autoHeight 来实现,当autoHeight 启用时,style.height 失效。 那就可以通过判断内容的长度来动态启用 autoHeight

1. 获取行数

通过 @linechange="handleLineChange" 来获取行数的话,初始状态下会立即调用,获取 event.detail 的内容。

{
    height22
    heightRpx38.55140186915888
    lineCount1
    lineHeight21.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 这种默认的情况。