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>

Logo

前往低代码交流专区

更多推荐