在公司业务中遇到这样一种情形:

需要根据input框里内容来实时改变input框的长度,否则input过长会影响拖拽,过短则会导致内容显示不全。

<input
    :id="index"
    type="text"
    placeholder="点击进行此处文本编辑"
    v-if="editWelcomeText"
    :disabled="isDisabled"
    v-model="item.textContent"
    :style="{
            height: item.fontSize * 16 + 'px',
            'line-height': item.fontSize * 16 + 'px',
            width: activeWidth(item),
            'font-size': item.fontSize + 'rem',
            color: item.color,
            'font-weight': item.fontWeight,
     }"
 />

这里就是简单的一个input标签,在style中通过activeWidth方法传入参数来动态计算文本的长度。

activeWidth(item) {
      let strLength = 0;
      let characterNums = 0;
      if (item.textContent === '') {
        return 10 * item.fontSize + 'rem';
      } else {
        let tempStr = item.textContent.split('');
        for (let i = 0; i < tempStr.length; i++) {
          // 判断字母数字特殊字符
          for (let j = 0; j < this.widthArray.length; j++) {
            if (this.widthArray[j].value.includes(tempStr[i]) === true) {
              strLength = this.widthArray[j].key * item.fontSize + strLength;
              characterNums = characterNums + 1;
            }
          }
        }
        strLength =
          strLength + (item.textContent.length - characterNums) * item.fontSize;
        return strLength + 'rem';
      }
    },

由于业务逻辑中需要遍历渲染多个input标签出来,item是从后台获取到的数据,大概的数据结构类似这样

{
    "welcomeModelId": 7,
    "dragId": "dragItem1",
    "textContent": "热烈欢迎",
    "width": 35,
    "height": 8,
    "top": 13,
    "marginLeft": 34,
    "fontSize": 7,
    "color": "#FEAB00",
    "fontWeight": 400
}

主要处理的就是textContent字段。

所以这里动态赋值input标签的width就通过textContent字段的长度 * fontSize即可;

但是这里后面出现了一个问题就是当输入数字,大小写字母,特殊字符时不能通过这样简单的计算来赋值,同样会导致input标签过长或者过短显示不全。

所以我们对不同字符的大小做了一个分类处理,以汉字大小为标准,如果汉字是1,按照比例对其他字符乘上不同的系数即可。

widthArray: [
        {
          // 5/18
          key: 0.28,
          value: "',.|:;I",
        },
        {
          // 6/18
          key: 0.34,
          value: 'ijl!(){}[]',
        },
        {
          // 7/18
          key: 0.39,
          value: 'frt ',
        },
        {
          // 8/18
          key: 0.45,
          value: 's_-"*',
        },
        {
          // 9/18
          key: 0.5,
          value: '1Jcvxyz/\\',
        },

        {
          // 10/18
          key: 0.56,
          value: 'ake?TL',
        },
        {
          // 11/18
          key: 0.62,
          value: '$ZF023456789',
        },
        {
          // 12/18
          key: 0.67,
          value: '#AVBYEKPSX',
        },
        {
          // 13/18
          key: 0.73,
          value: 'dbghnopquHDUCNR',
        },
        {
          // 14/18
          key: 0.78,
          value: 'w^<>=+~OQG',
        },
        {
          // 15/18
          key: 0.84,
          value: '&%M',
        },
        {
          // 17/18
          key: 0.95,
          value: 'mW',
        },
        {
          // 19/18
          key: 1.06,
          value: '@',
        },
      ],

维护这样一个对象数组,汉字大小取18份,注释为那一部分字符占的份数,即可计算出比例系数,对象中用key,value的形式存储比例系数和字符。

(这段真的不容易我和旁边的后端小哥辛苦测了半天才得出来的这个数组!)

然后就回到了上面的activeWidth方法,外层循环来遍历当前传入的item.textContent字段(先转成数组再遍历),然后内层循环来判断当前的字符应该乘以多少的比例系数,同时记录有多少个除了汉字以外的字符,两层循环走完以后计算总的长度,将长度这是为返回值即可。

感觉属于是特殊的需求没什么现成的办法给我们用这样自己造了一个轮子。分享给可能会需要的人!

Logo

前往低代码交流专区

更多推荐