vue-resumer 项目中 element-ui 遇到的 textarea autosize 问题

字数 1016阅读 1018
<el-input type="textarea" :autosize="{minRows:2}" v-model="amodel"></el-input>

如上边代码,element-ui 提供自动改变大小的 textarea 功能(这个功能详见)。

遇到问题表现

但是我的一个项目里,当 amodel 初始就有值的时候,他并不能调整大小,而是会出现滚动条,只有当修改内容的时候才会重新调整到合适大小。

解决过程

  1. 我首先想到的是这是不是个坑,然后就直接搜索其他人有没有遇到过,但我把项目的 issue 都找过了也没有找到,看来并不是一个常见的坑
  2. 接下来我就想能不能用笨办法先把问题解决,项目继续往下进行,我首先想到的是既然改变内容能把问题解决,那把对应的元素触发一遍 change 或者 input 事件之类的试一下,但是我并没有找到 elementUI 是什么事件才会触发 autosize,而且项目中的数据项较多,这个办法甚至有点蠢了
  3. 我继续思考,会不会是时机问题,因为我写的项目处的阶段是从 localstorage 拿数据,暂时还没写从服务端拿数据。我是在 created 阶段从 localstorage 读取的数据,而我查资料得到 elementUI 是在 mounted 阶段调整大小的,说明并不是这一问题。后来我才想到哪怕是先渲染然后再改变数据也应该是正常表现,这一思路完全不正确。
  4. 接下来我只能用更笨的办法逐步排查是什么问题
    1. 首先我新建一个空项目,写好 elementUI 的 hello world

    2. 然后写一个 autosize 的 textarea,分别测试了几个我认为引发问题的小因素,但都未重现

    3. 接下来把我原项目中的的部分数据和 template 代码拷贝到新项目,发现也没问题

    4. 然后我猜测是不是因为外层的循环导致或者是外边的容器导致的,所以我把更多的数据和 template 的结构拷贝的测试项目中,发现均没问题,有点方了……

    5. 我干了半个小时别的,回来继续想这个问题,我突然想到 4 中我复制代码的时候控制显示隐藏的数据没有拷贝过来(原项目中是有 tab 的,测试项目中没有,就没办法切换显示隐藏,所以我就没拷贝),报了错,然后我直接写死了(写成 true)。隐藏用 v-show 控制的,实际上是 display:hidden,我就想到是不是隐藏的元素 elementUI 就不 autosize 了。然后我马上在原项目中测试,将其中一个出现问题的 tab 设置为默认的 tab,果然没问题的,问题的原因终于确定了。原项目中有好几个 tab 需要 autosize,刚才设置默认 tab 这种方法肯定是不行的,那么换一种控制显示隐藏的方法就好了,因为我换了v-show,虽然 tab 这种需要频繁切换的用v-show更合适,但是为了解决这个问题也只能这么做了。

      一般来说, v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件不太可能改变,则使用 v-if 较好。

ps:只是记录自己的思考过程,所以行文比较凌乱,语法也可能有问题,见谅。

PPS:在 GitHub 提了个 issue,得到的解决方案是:

  1. 为 input type=textarea 增加ref。比如ref='userInfo'
  2. 在v-show的值发生变化时,调用this.$refs.userInfo.resizeTextarea(),调用方法如下:
this.$nextTick(function () {
vmSelf.$refs.userInfo.resizeTextarea();
});

推荐阅读更多精彩内容