Vue 自定义指令:替代 el-input
的 autosize
,解决当el-input设置css样式 word-break: break-all
时下文本域高度计算异常问题
在使用 Element UI 的 el-input
组件时,type为textarea
且 设置 word-break: break-all
样式后,会导致 autosize
属性计算高度不准确,当输入中英文数字时有时会多出一行空行,影响用户体验,这一点可直接在 Element UI官网F12修改示例样式后,输入指定输入框内容来复现。
解决方案
基于此,自定义了一个 Vue 指令 v-autosize
,用来替代 el-input
默认的 autosize
,通过一个隐藏的测量元素实时计算 textarea
的内容高度,从而精准调整输入框高度。
代码实现
/**
* 解决el-input type为textarea时,如果设置word-break: break-all时,
* 输入框中输入中英文数字内容时autosize计算高度有时不正确,
* 用于替代el-input默认的autosize属性
*/
const autosize = {
inserted(el) {
const textarea = el.querySelector('textarea');
if (!textarea) return;
// 创建测量用的隐藏div
const mirror = document.createElement('div');
Object.assign(mirror.style, {
position: 'fixed',
visibility: 'hidden',
whiteSpace: 'pre-wrap',
wordBreak: 'break-all',
width: getComputedStyle(textarea).width,
padding: getComputedStyle(textarea).padding,
font: getComputedStyle(textarea).font,
lineHeight: getComputedStyle(textarea).lineHeight,
boxSizing: 'border-box',
});
document.body.appendChild(mirror);
// 更新输入框高度
function update() {
mirror.textContent = textarea.value + '\n';
textarea.style.height = mirror.offsetHeight + 'px';
}
// 初始化并监听输入及尺寸变化
update();
textarea.addEventListener('input', update);
new ResizeObserver(update).observe(textarea);
// 解绑时清理
el._cleanup = () => {
document.body.removeChild(mirror);
};
},
unbind(el) {
el._cleanup && el._cleanup();
},
};
Vue.directive('autosize', autosize);
使用说明
- 注册该指令后,在
el-input
组件上添加v-autosize
即可:
<el-input type="textarea" v-autosize v-model="text" />
- 该指令通过隐藏元素同步计算高度,适配了
word-break: break-all
布局,避免了默认autosize
在某些情况下高度计算不准的问题。
总结
通过这个指令,可以保证带有 break-all
样式的多行输入框在内容变化时自动调整高度,提升表单输入的体验和稳定性。适合在 Element UI库遇到 textarea
高度计算异常时使用。