利用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;
 },

至此,需求成功实现。

相关推荐
ynchyong40 分钟前
微信小程序启动顺序遇到的一个坑
前端·微信小程序
用户2333768521842 分钟前
接口卡死排查实录-缺失return的UB死循环
前端·后端
光影少年1 小时前
如何实现RN 多环境、多渠道打包
前端·react native·react.js
闲坐含香咀翠1 小时前
百万行数据透视表,我是怎么把 Vue 响应式开销砍到零的
前端·vue.js·性能优化
xiaopang1 小时前
小红书小组件(miniwidget)开发实战:单页面viewState切换架构
前端
labixiong1 小时前
告别scroll 监听:CSS 滚动驱动动画,主线程堵死也仍跟手
前端·css·html
云析赢指标公式网42 小时前
文华WH6布林轨道均线强弱共振指标公式
前端·算法
许彰午2 小时前
34-安全复盘96个问题
前端·vue.js·安全
妙码生花2 小时前
PHP 各框架下和 Go 的性能比较
前端·后端·go
Csvn2 小时前
TypeScript 类型性能:让类型体操不再卡死编译器
前端