likes
comments
collection
share

利用el-input组件实现一组特殊的公式input框!

作者站长头像
站长
· 阅读数 53

最近接到一个需求(Vue2+elmentUI项目),要做一个如下图的公式input框。该input框需要支持插入文本,且只能出现图中红框圈出来的文本。

利用el-input组件实现一组特殊的公式input框!

经过一番考量和商量,将上述需求分解为以下两大功能点实现。

一、input框做特殊处理:只允许插入,不允许输入,但支持键盘删除

支持键盘删除这点,就决定了不能用el-input组件自带的disabled和readonly属性来实现input不允许输入的需求。

那么怎么实现不允许输入但支持键盘删除这个需求呢?

方案一:

el-input组件绑定值用value写法,然后在input事件中进行判断,只有绑定值大于回调参数value时,才将回调参数value的值赋值给绑定值,具体代码如下:

<el-input 
  :value="item.indexFormulasDesc" 
  placeholder="" 
  clearable
  @input="(value)=>{
    if(item.indexFormulasDesc.length > value.length) {
      item.indexFormulasDesc = value
   }"
 ></el-input>

一开始,我用的就是这个方法,后来在测试过程中发现,用back键(退格键)进行删除时,只能从最后一个字符开始删,如果移动光标从文本中间删,则无法删除,光标自动跳到文本的结尾。

起初,以为是光标定位出了问题,然后各种排查解决,但问题依然存在,后来 经过一番探索,发现是back键删除时,el-input组件中的value属性绑定值item.indexFormulasDesc与input方法中的回调参数value的值不能同步造成的。

于是,又开始尝试让value属性绑定值与input方法中的回调参数value的值同步,但多方尝试无果后,探索出了下面的方案二。

方案二:

将el-input组件的maxlength属性的值设置为0,其绑定值采用v-model的写法。具体代码如下:

<el-input 
  v-model="item.indexFormulasDesc"  
  placeholder="" 
  clearable
  maxlength="0"
></el-input>

此方法可完美实现需求,而不会发生退格键删除问题。

二、根据光标进行定位,将文本插入到想要插入的地方

要实现这一点,需要经历两步。

第一步:定义一个变量inputIndex,在el-input组件blur事件中,将当前光标所在的input框的index赋值给变量inputIndex。

在后续插入操作中,我们可以根据变量inputIndex的值,知道我们当前要操作的是哪一个input框。

  <div 
    v-for="(item,index) in indexFormulasListOne" 
    :key="index"
    class="index-Formulas-item"
   >
     <div style="flex: 1;display: flex;align-items: center;">
       <span>{{ index + 1 }}.</span>
       <el-input 
          :id="`inputRef${index}`" 
          v-model="item.indexFormulasDesc" 
          placeholder="" 
          maxlength="0" 
          clearable
          @blur="(e)=>{
            // 关键代码
            inputIndex = index
          }"
        ></el-input>
      </div>     
     <div class="del-icon" v-if="indexFormulasListOne&&indexFormulasListOne.length > 1">
      <svg-icon icon-class="delete" class="del-ic" @click="handleDelFormulas('one',index)" />
      </div>
  </div>

第二步:封装插入文本的公共方法,在需要的地方调用,最终实现根据光标位置插入指定文本的需求,具体代码如下:

  /** 在光标前插入文本
 * id:input绑定的id,
 * insertTxt:要插入的文本
 */
 insertInputTxt(id, insertTxt) {
    // 获取dom:此处用id的方法获取dom,也可用ref的方法获取dom
    const elInput = document.getElementById(id);
    // 获取光标开始位置
    const startPos = elInput&&elInput.selectionStart;
    // 获取光标结束位置
    const endPos = elInput&&elInput.selectionEnd;
    if ( !(startPos || startPos === 0) || !(endPos ||  endPos === 0)) return;
    const txt = this.indexFormulasListOne[this.inputIndex].indexFormulasDesc;
    //在光标前插入文本
    const result = txt.substring(0, startPos) + insertTxt + txt.substring(endPos);
    //对应input框出现插入的文本
    this.indexFormulasListOne[this.inputIndex].indexFormulasDesc = result;
    //文本插入后,光标重新聚焦
    elInput.focus();
    elInput.selectionStart = startPos + insertTxt.length;
    elInput.selectionEnd = startPos + insertTxt.length;
 },

至此,需求成功实现。

转载自:https://juejin.cn/post/7303423871710527523
评论
请登录