思路:首先,input框肯定不能支持此需求,因为不支持enter换行的功能。直接想到textarea。
用textarea,先指定rows为1。在textarea的onInput事件中,获取textarea的clientHeight、scrollHeight。当scrollHeight每次大于clientHeight时,rows++。当rows为5时,指定此时clientHeight为max-height。
这样,,行数增加时可以实现功能。但是删除内容时,scrollHeight与clientHeight相等且不变,不能获取到用户当前在删除。
为什么呢:高度为textarea组件高度,并不是用户实际输入内容的高度。scrollHeight是包含溢出部分的高度,textarea高度增加到max-height时,删除内容,scrollHeight不变。
解决:
使用标签可编辑属性:contenteditable,此属性支持动态行数。上代码:
<div ref="inputTextField"
id="inputTextField"
contenteditable="true"
class="placeholder-class textaera-inner"
@input="onInput"
placeholder="有问题可以直接向我提问"
:value="inputContent"
tabindex="1"
onfocus="onFocus()"
onblur="onBlur()">
</div>
1.用css调整成textarea的样式。
注意:直接写placeholder是没有占位符效果的,需结合伪类。
.placeholder-class:empty::before {
content: attr(placeholder);
color: #d3d4d6;
}
.placeholder-class:focus {
outline: none;
}
2.tabindex
指示其元素是否可以聚焦。等于1时:表示元素是可聚焦的。div元素获取焦点时需加上此属性。onFocus(),onBlur()函数直接在methods中写,会报错undefined。需要挂载在window上。在created中调用。
const $this = this
window.onFocus = () => {
return (() => {
$this.onFocus()
})()
}
window.onBlur = () => {
return (() => {
$this.onBlur()
})()
}
3.div不能使用v-model进行双向绑定。v-bind绑定value为inputContent。在@input事件中,实时更新inputContent。
onInput(event) {
this.inputContent = event.target.innerText
}
但存在Bug:inputContent更新时,value不能更新。只能通过document.getElementById('inputTextField').innerText直接赋值。目前这莫写的,需求实现了,再优化~。