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

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

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

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

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

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

方案一:

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

js 复制代码
<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的写法。具体代码如下:

js 复制代码
<el-input 
  v-model="item.indexFormulasDesc"  
  placeholder="" 
  clearable
  maxlength="0"
></el-input>

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

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

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

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

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

js 复制代码
  <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>

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

js 复制代码
  /** 在光标前插入文本
 * 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;
 },

至此,需求成功实现。

相关推荐
视觉CG10 分钟前
【Viewer.js】vue3封装图片查看器
开发语言·javascript·vue.js
java1234_小锋23 分钟前
一周学会Flask3 Python Web开发-redirect重定向
前端·python·flask·flask3
GDAL31 分钟前
UniApp SelectorQuery 讲解
vue.js
琑9541 分钟前
nextjs项目搭建——头部导航
开发语言·前端·javascript
light多学一点1 小时前
视频的分片上传
前端
计算机学姐1 小时前
基于SpringBoot的校园消费点评管理系统
java·vue.js·spring boot·后端·mysql·spring·java-ee
Gazer_S1 小时前
【Windows系统node_modules删除失败(EPERM)问题解析与应对方案】
前端·javascript·windows
bigyoung1 小时前
基于 React 的列表实现方案,包含创建和编辑状态,使用 Modal 弹框和表单的最佳实践
前端
乌木前端2 小时前
包管理工具lock文件的作用
前端·javascript
司玄2 小时前
3dtiles平移旋转原理及可视化工具实现
前端