使用<el-input type="textarea">
组件来自Vue的Element UI库时,如果想在输入时实时监听输入并替换某些内容,同时又希望保持光标位置不变(即在内容被替换后光标不自动跳到内容的最后位置),可以通过以下方式来实现:
方法1:使用input
事件和setSelectionRange
方法
在Vue中,监听input
事件,然后使用JavaScript的setSelectionRange
方法来设置光标位置。
<template>
<el-input
type="textarea"
ref="myTextarea"
v-model="inputText"
@blur="handleblur"
@input="handleInput"
></el-input>
</template>
<script>
export default {
data() {
return {
inputText: ''
};
},
methods: {
handleInput() {
// 获取光标位置
let cursorPosition = this.$refs.myTextarea.$refs.textarea.selectionStart;
// 对输入内容进行替换处理,这里以简单的中文逗号替换英文逗号为例
this.inputText = this.inputText.replace(/,/g, ',');
// 恢复光标位置
this.$nextTick(()=>{
this.$refs.myTextarea.$refs.textarea.setSelectionRange(cursorPosition, cursorPosition)
})
},
handleblur() {
// 失去焦点,处理多个逗号和连续超过两个逗号替换成只要一个逗号
if(this.inputText) {
this.inputText = this.inputText.trim().replace(/\s*(,)\s*/g, ',').replace(/,{2,}/g, ',')
}
},
}
};
</script>
方法2:使用计算属性控制显示值和内部值分离
如果不在input
事件中直接操作DOM,可以通过计算属性来控制显示的文本和实际的文本存储在不同的变量中。
<template>
<el-input
type="textarea"
ref="myTextarea"
v-model="inputText"
@blur="handleblur"
@input="handleInput"
></el-input>
</template>
<script>
export default {
data() {
return {
inputText: '', // 显示给用户的文本,可能经过处理或未处理
internalText: '', // 实际存储的文本
};
},
watch: {
internalText(newVal) {
this.inputText= newVal; // 确保视图更新时,显示的文本也是最新的内部文本
}
},
methods: {
handleInput() {
// 处理文本
let newValue = this.$refs.myTextarea.$refs.textarea.value.replace(/,/g, ',');
// 获取光标位置
let cursorPosition = this.$refs.myTextarea.$refs.textarea.selectionStart;
// 更新显示值(但不触发渲染)
this.$refs.myTextarea.$refs.textarea.value = newValue;
// 恢复光标位置
this.$nextTick(()=>{
this.$refs.myTextarea.$refs.textarea.setSelectionRange(cursorPosition, cursorPosition)
})
// 更新内部存储的文本值,不会触发视图更新,除非通过watch监听器
this.internalText = newValue;
},
handleblur() {
// 失去焦点,处理多个逗号和连续超过两个逗号替换成只要一个逗号
if(this.inputText) {
this.inputText = this.inputText.trim().replace(/\s*(,)\s*/g, ',').replace(/,{2,}/g, ',')
}
},
}
};
</script>