emahiro/b.log

日々の勉強の記録とか育児の記録とか。

Vue3 で TextArea を入力に応じて可変させる

Overview

タイトルのとおりです。
ちゃんとアプリとかにありがちな TextArea の入力量(改行)に応じて、TextArea を拡張させる実装のサンプルを記載します。

結構ありがちな実装だと思いますが、Vue3 のサンプルが少なかったのでかんたんなサンプルコードを書いてみました。

Sample

<script setup>
import { ref, watchEffect } from 'vue'

const msgInput = ref('')
const msgTextArea = ref(null);
  
watchEffect(()=>{
  // デフォルトのテキストエリアの大きさを指定する。
  msgTextArea.value?.style.setProperty('height', `30px`)
  
  if(msgInput.value !== ''){
    //
    msgTextArea.value?.style.setProperty('height', `${msgTextArea.value?.scrollHeight}px`)
  }
  
})
</script>

<template>
  <h1>Title</h1>
  <textarea 
            v-model="msgInput"
            placeholder="input"
            ref="msgTextArea"
  />
</template>

ref: https://sfc.vuejs.org/#eNqVUs2K1EAQfpW2ETIDM2nF25iM7EHQm4c99mFjtjLJ0uluujuzuwwBJwFXUC+CBz2K4B/u3edp1uewkkxk1EXYXNJV9dVXX/1s6IHW4boCuqCRTU2hHbHgKr3ksii1Mo5siIFsRk4Tl+YPswxSR2qSGVWSAPMCLrlMlbSOlHb1WOrKkbjLmATBdC9yCGfuwECyC8pKiOl9Lgnhco95MpnGy03nZoz49sK3b33zxbfffPvCby99+9w3333zozObz7796psP6L/6+MlvX/stgt/8fHVxdfneb9/55qV/1nRce+XDdSIqeBBady4gxE6fGKXBuPNJkEOxyl0wI0f37uizIxTfiSOkyCZjZ0M2uRXHBLvrdXZKh/9Nq9zeXJeRGiXEox5UjyrqQUqNRsSGJeF60HBQapE4QIuQKL+7PCycgIjhq/c4ZE+6oQ8Kx289L9UxiJjTsTFO/0Qgawq5EsdgEFVcB8EtDgRjCwOAYeWI/RZGZ3Q4o3mZ6PDEKomH1g8OafuA5XRBdqPkFC+qsznNndN2wZjN0u48T2yozIrhKzSVdEUJIdhy/tSoUwsGiTmd7XEwdK7BzA1IbAHM/zj/gv7Du9tATetf01coHg==

実際の動作は以下の様になります。

ハマったところ

vue3 ref height textarea expand みたいなキーワードでググるといくつかサンプルが出てきますが、Vue3 のものがなく、ref で指定した DOM の要素をどうやって SFC の script のところで取り回せるかわからなかったのですが、結論から先にいうと ref の名前と高さをいじりたい textarea を格納する変数名を同じにする ということでした。
つまりここでいうと ref="msgTextArea" と textarea に ref を貼った場合、script 内で使用する変数も msgTextArea とする必要があります。これが最初わからず時間を溶かしました。