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

至此,需求成功实现。

相关推荐
_.Switch40 分钟前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光44 分钟前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   1 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   1 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web1 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常1 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇2 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
Jiaberrr2 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
Tiffany_Ho3 小时前
【TypeScript】知识点梳理(三)
前端·typescript
安冬的码畜日常4 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js