vue3如何实现自适应高度的textarea

1,317 阅读1分钟

前言

最近在仿照antDesign写点组件,先分享个自适应高度textarea组件的实现方式。

功能介绍

一共两种情况:

  1. 根据你输入内容自动调整高度。
  2. 你自己设置最小和最大行数,在最大行数以内的会自动调整高度,而超过最大行数的会出现滚动条

具体效果可以看AntDesign Vue 的Input这一栏的多行文本的效果,功能一样。

image.png

以上就是背景,下面是具体代码:

具体代码

<template>
  <textarea :placeholder="placeholder" ref="textAreaRef" v-model="content" :rows="minRow ?? 1"
            class="ant-input"></textarea>
</template>

<script lang='ts'>
import {onMounted, ref, watch, nextTick} from 'vue';

export default {
  props: {
    autoSize: [Boolean, Object],
    placeholder: String
  },
  setup(props) {
    let {minRow, maxRow} = props?.autoSize;
    const textAreaRef = ref<HTMLTextAreaElement>(null);
    const content = ref('');
    onMounted(() => {
      props.autoSize && nextTick(adjustTextareaSize);
    });
    watch(() => content.value, () => {
      props.autoSize && nextTick(adjustTextareaSize);
    });
    const adjustTextareaSize = () => {
      let textarea = textAreaRef.value;
      textarea.style.height = 'auto';
      if (maxRow) {
        textarea.style.maxHeight = maxRow * 24 + 'px';
      }
      const height = textarea.scrollHeight;

      if (height) { // 改变textarea高度达到自适应
        textarea.style.height = height + 'px';
        const rowsNum = Math.round(height / 24);
        textarea.style.overflowY = rowsNum > maxRow ? 'scroll' : 'hidden';
      }
    };

    return {textAreaRef: textAreaRef, content, minRow};
  }
};
</script>

<style lang='scss' scoped>
// 注:ant-input 是直接照搬antDesign的input输入框的样式,这里没写进来
textarea.ant-input {
  max-width: 100%;
  height: auto;
  min-height: 32px;
  line-height: 1.5715;
  vertical-align: bottom;
  transition: all .3s, height 0s;
}

textarea {
  height: 32px;
  resize: none;
  overflow: hidden;
}
</style>