千家信息网

Vue中textarea自适应高度方案怎么实现

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"Vue中textarea自适应高度方案怎么实现"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学
千家信息网最后更新 2026年11月02日Vue中textarea自适应高度方案怎么实现

本篇内容介绍了"Vue中textarea自适应高度方案怎么实现"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

隐藏的问题

抛开原生JS,框架的大部分UI库都支持自适应textarea高度功能,但普遍都忽略了一个功能,就是自适应高度的回显。

使用这些库的时候,我们很容易的在textarea中键入内容,超出范围时会自动延展一行,保证内容高度的自适应。当我们提交内容,在其它页面使用同样的UI来渲染时,麻烦的就来了,有些UI库是不支持自适应回显的,这就需要我们通过行高、行数甚至高度之间的计算得出一个基值,从而实现回显。

解决自适应高度的方案

常见得方案有两种,一种是在页面地"边远地区"添加一个ghost dom来模拟输入换行,这个dom的可能是editable属性为true的div或者是一个一摸一样得textarea。
以element-ui的input组件举例,当我们在组件内输入值时,会调用resizeTextarea方法

resizeTextarea() {  if (this.$isServer) return;  const { autosize, type } = this;  if (type !== 'textarea') return;  if (!autosize) {    this.textareaCalcStyle = {      minHeight: calcTextareaHeight(this.$refs.textarea).minHeight    };    return;  }  const minRows = autosize.minRows;  const maxRows = autosize.maxRows;  this.textareaCalcStyle = calcTextareaHeight(this.$refs.textarea, minRows, maxRows);}

当设置了autosize为true则textarea设为自适应高度。此时textarea的高度会通过calcTextareaHeight方法实时计算。

export default function calcTextareaHeight(  targetElement,  minRows = 1,  maxRows = null) {  if (!hiddenTextarea) {    hiddenTextarea = document.createElement('textarea');    document.body.appendChild(hiddenTextarea);  }  let {    paddingSize,    borderSize,    boxSizing,    contextStyle  } = calculateNodeStyling(targetElement);  hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`);  hiddenTextarea.value = targetElement.value || targetElement.placeholder || '';  let height = hiddenTextarea.scrollHeight;  const result = {};  if (boxSizing === 'border-box') {    height = height + borderSize;  } else if (boxSizing === 'content-box') {    height = height - paddingSize;  }  hiddenTextarea.value = '';  let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize;  if (minRows !== null) {    let minHeight = singleRowHeight * minRows;    if (boxSizing === 'border-box') {      minHeight = minHeight + paddingSize + borderSize;    }    height = Math.max(minHeight, height);    result.minHeight = `${ minHeight }px`;  }  if (maxRows !== null) {    let maxHeight = singleRowHeight * maxRows;    if (boxSizing === 'border-box') {      maxHeight = maxHeight + paddingSize + borderSize;    }    height = Math.min(maxHeight, height);  }  result.height = `${ height }px`;  hiddenTextarea[xss_clean] && hiddenTextarea[xss_clean].removeChild(hiddenTextarea);  hiddenTextarea = null;  return result;};

我们可以看到

if (!hiddenTextarea) {  hiddenTextarea = document.createElement('textarea');  document.body.appendChild(hiddenTextarea);}

element-ui创建了一个textarea的dom,通过calculateNodeStyling方法将真正的textarea的样式复制给hiddenTextarea(overflow不同步,真正的textarea是为hidden)。接着监听textarea的输入值,同步给hiddenTextarea。同时将hiddenTextarea的scrollHeight同步给textarea的高度,最后再将dom销毁掉。

关于样式的同步,element这里用了getComputedStyle和getPropertyValue这两个API。当然,如果你自己封装的话,也可以使用css预处理器的mixin。

第二种方案与第一种方案类似,不过不会创建额外的dom。以开头的vue-awesome-textarea举例:

init() {  this.initAutoResize()},initAutoResize () {  this.autoResize && this.$nextTick(this.calcResize)}

在页面mounted或者内容变动且开启自适应高度autoResize的时候,执行this.calcResize方法。

calcResize() {  this.resetHeight()  this.calcTextareaH()},resetHeight() {  this.height = 'auto'},calcTextareaH() {  let contentHeight = this.calcContentHeight()  this.height = this.calcHeightChange(contentHeight) + 'px'  if (this.needUpdateRows(contentHeight)) {    this.updateRows(contentHeight)  }  this.oldContentHeight = contentHeight},calcContentHeight () {  const { paddingSize } = this.calcNodeStyle(this.$el)  return this.$el.scrollHeight - paddingSize},

resetHeight()是来初始化textarea的高度,默认为auto。calcTextareaH()方法是用来计算内容区域的高度(textarea的scrollHeight减去padding的高度),同时将计算好的高度实时同步给textarea的高:
this.height = this.calcHeightChange(contentHeight) + 'px'

相比方案一,这个方案采用的思路相同(动态修改高度),但是减少了额外的dom创建和销毁的过程。
此外,vue-awesome-textarea还支持在自适应的过程中回调行数,可以更好的支持数据回显。实现的方法也很简单:

computed: {  ...  oneRowsHeight() {    return this.calcContentHeight() / Number(this.rows) || 0  }  ...}

在computed中我们计算出单行的高度,同时在执行this.calcTextareaH()方法时我们记录下内容高度:

this.oldContentHeight = contentHeight

接着我们会比对是否存在添加行操作,一旦添加则新的内容高度和老的内容高度会不同:

needUpdateRows(newContentHeight) {  return this.oldContentHeight !== newContentHeight},

此时我们会把最新的行高emit到组件外部:

updateRows(contentHeight) {  this.$emit('getRows', Math.round(contentHeight / this.oneRowsHeight))}

"Vue中textarea自适应高度方案怎么实现"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

高度 内容 方案 方法 同步 支持 同时 组件 过程 页面 输入 功能 实时 时候 更多 样式 知识 不同 实用 相同 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 咖啡 中国互联网科技工作委员会毛军 奇酷互联网络科技 沃里互联网科技 苏州大垚互联网科技 济南和联互联网科技有限公司 银川新华互联网科技学校地址 互联网汽车科技小镇 重庆威客帮互联网科技 南平创想时代互联网科技有限公司 互联网公司黑科技创始人 互联网在线教育科技创业 互联网科技圈年度人物 九思连强互联网电子科技有限公司 济南小医互联网科技有限公司招聘 吉林省码上互联网科技电话 盐城市攀科互联网科技有限公司 河南商务圈互联网科技有限公司 科技美学互联网 艺术 互联网科技创业有什么好项目 互联网科技公司发展 互联网 视角下的科技创新 大白互联网科技 科技类的互联网平台 互联网教育科技公司vipkid 南通创西澳互联网科技有限公司 版纳互联网科技选哪家 保山互联网科技靠谱吗 同城互联网络科技 上海旺乐尼互联网科技有限公司
0