vue 字符串模板 textarea中插入文字标签
<template><div><el-form label-width="80px"><el-form-item label="内容"><el-inputref="smsInput"type="textarea":rows="4"v-model="smsContent"placeholder="请输入内容"
·
1.字符串模板以“[“开始 以“]”结束 是一个元素
2.按下backspace退格键或者delete删除键删除字符时,如果删的是字符串模板,会删除整个字符串模板元素
3.选择文字元素后,会选择整个的字符串模板
4.字符串模板得到焦点后会将焦点移动到字符串模板后
<template>
<div>
<el-form label-width="80px">
<el-form-item label="内容">
<el-input
ref="smsInput"
type="textarea"
:rows="4"
v-model="smsContent"
placeholder="请输入内容"
@input.native="smsInput"
@blur="inputBlur"
@focus="focusHandler"
@click.native="focusHandler"
@keydown.up.down.left.right.native="focusHandler"
@select.native="selectHandler"
></el-input>
</el-form-item>
</el-form>
<el-popover
style="margin-left: 10px; float: right;"
placement="right-start"
width="200"
v-model="visible"
trigger="manual"
>
<div class="insert-list">
<p class="i-title">元素列表</p>
<div v-for="(item,index) in btns" :key="index">
{{item}}
<el-button @click="insertStr('['+item+']')" size="mini" type="primary"
>插入</el-button
>
</div>
</div>
<el-button
slot="reference"
size="small"
@click="visible = !visible"
type="primary"
>插入元素</el-button
>
</el-popover>
</div>
</template>
<script>
export default {
data() {
return {
smsContent: "",
inputFocus: null,
visible: false,
btns:[
'姓名',
'费用',
'日期',
'电话号码',
'发件人',
]
};
},
methods: {
// 插入元素
insertStr(str) {
let before = this.smsContent.slice(0, this.inputFocus);
let after = this.smsContent.slice(
this.inputFocus,
this.smsContent.length
);
this.inputFocus = this.inputFocus + str.length;
this.smsContent = before + str + after;
this.$emit("smsText", this.smsContent);
},
// 保存光标位置
inputBlur(e) {
this.inputFocus = e.target.selectionStart;
this.visible = false;
},
// 删除元素剩余部分
smsInput(e) {
//deleteContentBackward==退格键 deleteContentForward==del键
if (
e.inputType == "deleteContentBackward" ||
e.inputType == "deleteContentForward"
) {
let beforeIndex = 0;
let afterIndex = 0;
// 光标位置往前
for (let i = e.target.selectionStart - 1; i >= 0; i--) {
if (this.smsContent[i] == "[") {
beforeIndex = i;
afterIndex = e.target.selectionStart;
break;
}
if (this.smsContent[i] == "]") {
break;
}
}
// 光标位置往后
for (let i = e.target.selectionStart; i < this.smsContent.length; i++) {
if (this.smsContent[i] == "]") {
afterIndex = i+1;
beforeIndex = e.target.selectionStart;
break;
}
if (this.smsContent[i] == "[") {
break;
}
}
if(beforeIndex == 0 && afterIndex == 0){
return
}
let beforeStr = this.smsContent.slice(0,beforeIndex)
let afterStr = this.smsContent.slice(afterIndex)
this.smsContent = beforeStr+afterStr
this.inputFocus = beforeStr.length
this.$nextTick(() => {
this.changeFocus(e.target, this.inputFocus, this.inputFocus);
});
}
this.$emit("smsText", this.smsContent);
},
// 选择元素剩余部分
selectHandler(e) {
// 光标开始位置往前
for (let i = e.target.selectionStart - 1; i >= 0; i--) {
if (this.smsContent[i] == "[") {
this.changeFocus(e.target, i, e.target.selectionEnd);
break;
}
if (this.smsContent[i] == "]") {
break;
}
}
// 光标结束位置往后
for (let i = e.target.selectionEnd; i < this.smsContent.length; i++) {
if (this.smsContent[i] == "]") {
this.changeFocus(e.target, e.target.selectionStart, i + 1);
break;
}
if (this.smsContent[i] == "[") {
break;
}
}
},
// 焦点跳出元素内
focusHandler(e) {
setTimeout(() => {
let selStart = e.target.selectionStart
let beforeArrLength = this.smsContent
.slice(0, selStart)
.split("[").length;
let afterArrLength = this.smsContent
.slice(0, selStart)
.split("]").length;
//根据'['和']'生成两个数组 判断数组长度 是否相等 不相等就不成对就移动光标
if (beforeArrLength != afterArrLength) {
let pos = this.smsContent.indexOf("]", selStart) + 1
if(beforeArrLength > afterArrLength && e.code == 'ArrowLeft'){//按下按键左箭头
pos = this.smsContent.lastIndexOf("[",selStart)
}
this.changeFocus(e.target,pos,pos);
}
}, 100);
},
// 修改光标位置
changeFocus(target, start, end) {
let range,
el = target;
if (el.setSelectionRange) {
el.setSelectionRange(start, end);
} else {
range = el.createTextRange();
range.collapse(false);
range.select();
}
},
},
};
</script>
<style scoped>
.insert-list p {
text-align: center;
}
.insert-list div {
margin: 10px 0;
display: flex;
justify-content: space-between;
}
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)