使用 VueJS 自动调整 Textarea 大小的问题

Question for auto-resizing Textarea using VueJS

我正在尝试让文本区域在文本值更改时自动调整其高度:

<textarea ref="textarea" v-model="message"> </textarea>

我使用观察器来监视与文本区域关联的组件变量“消息”。每当消息发生变化时,都会触发一个函数来调整textarea的高度:

watch: {
  message: function(){
    this.$refs.textarea.style.height="auto";
    this.$refs.textarea.style.height = this.$refs.textarea.scrollHeight + 'px';
  },
}

如果我在框内手动键入,代码运行良好。但是,如果我使用方法更新文本区域变量“消息”,则框的大小不会正确更新。

为了更清楚,我创建了一个 fiddle 项目:https://jsfiddle.net/ttl66046/9nycdq60/4/ 代码笔在这里:https://codepen.io/ttl66046/pen/eYGqJWm

文本框下方有两个按钮。每个按钮都与一个短文本相关联。理想情况下,文本框的高度应根据您单击的按钮(您选择的文本)进行更新。这里有什么问题?

在css中添加以下代码:

textarea {
    width:200px;
    resize:none;
  }

直到 下一个 渲染周期才会渲染观察者的效果。 message 观察者设置 height 两次(一次设置为 auto 然后 立即 scrollHeight 覆盖它),但组件不会re-render 在每个设置之间。

关键是在下一个渲染周期中用 $nextTick() callback:

更新 height
export default {
  watch: {
    message: function() {
      this.$refs.textarea.style.height = "auto";
               
      this.$nextTick(() => {
        this.$refs.textarea.style.height = this.$refs.textarea.scrollHeight + 'px';
      })
    }
  }
}

updated codepen

如果你想在更改 TEXT 时使用“+”行和“-”行,请使用 Vue3(对我来说,组合 API):

            <textarea
               id="newComm"
               class="form-control"
               name="comment"
               placeholder="Some text you want"
               cols="30"
               :rows="rowsHeight"
               wrap="soft"
               v-model.trim="newCommText"
               @input="changeRows"
               :style="'resize: none; overflow: hidden; line-height: '+lineHeight+'px;'"
        ></textarea>

    setup() {
    /*--------your code here--------*/

    const newCommText = ref(null)
    const rowsHeightStart = ref(5)
    const rowsHeight = ref(rowsHeightStart.value)
    const lineHeight = ref(25)
    function changeRows (event) {
        rowsHeight.value = event.target.value.split("\n").length > rowsHeightStart.value ? event.target.value.split("\n").length : rowsHeightStart.value
    }

    return {
         rowsHeight, lineHeight, newCommText,
        changeRows
    }