Vue.js让前端飞

Vue | 指令实现自动翻译填充英文名功能

2021-05-21  本文已影响0人  Ygria

实现效果

转全拼 转英文(伪)

方案调研

对需求进行分析后,对于如何将中文名翻译成英文字符串,调研以下方案:

以上三种仅为中转英的方法不同,均可实现功能。本次方案暂使用第三种。

实现方案

  1. 为中文名的输入框绑定监听事件,监听输入,取得该input框输入的值
  2. 将第一步中获得的中文值转化成英文字符串
  3. 将英文字符串写入到英文名输入框中
    思路: 为表单添加vue自定义指令,通过取子节点(根据虚拟节点层级,vnode的子级)的方法,获取到需要操作的dom元素,再在指令逻辑中进行逻辑处理。

代码实现

指令定义

import { transliterate as tr, slugify } from 'transliteration'
export default {
  inserted(el, binding, vnode) {
    let sourceInputEl = vnode.componentInstance.$children.find(item => item.prop === 'name').$children[1].$el.children[0]
    let targetInputEl = vnode.componentInstance.$children.find(item => item.prop === 'key').$children[1].$el.children[0]

    let isFirstInput = true;

    sourceInputEl.addEventListener('keyup', () => {
      // 判断当前标识是否已填写,若已填写,则不再根据中文名称生成
      let isEmpty = !targetInputEl.value;

      if (isEmpty || !isFirstInput) {
    // 一定延迟处理,用户使用几乎无感知
        setTimeout(() => {
          let transValue = slugify(sourceInputEl.value, { separator: '_' });
          let inputEvt = new InputEvent('input', {
            inputType: 'insertText',
            data: transValue,
            dataTransfer: null,
            isComposing: false
          });
          targetInputEl.value = transValue;
          targetInputEl.dispatchEvent(inputEvt);
          isFirstInput = false;

        }, 500);
      }
    })

  }
}

注意事项

1、transValue的生成可根据前面所说的不同方案,更改生成的方法。
2、两个input 元素是根据prop来筛选的,代码中硬编码为”name“ -中文名 和”key“ 英文名,可根据需求调整,也可以根据指令方法入参的binding赋值。由于本项目中所有表单prop都是固定的,所以没有写相应逻辑。
3、keyup事件可根据需求更改为blur事件,对于调用后台api获值,可考虑改为blur,降低频繁请求。
4、执行targetInputEl.value = transValue; 后,页面上显示已经改变,但点击保存表单时仍然会触发空值校验,怀疑是因为该赋值没有刷新到虚拟节点的model中,故而使用 targetInputEl.dispatchEvent(inputEvt);方法模拟输入事件,触发值的刷新。
5、isEmpty 空值校验,避免用户在填写表单时先填写了英文名,再填写中文名时,英文名被覆盖。逻辑一般限定标识生成后就不允许修改,该方法也规避了修改时的英文名跟着中文名修改的问题。
6、使用transliterate可定义配置字典,实现常用中-英单词的翻译,但仍然无法替代翻译引擎。配置逻辑参考github上的README即可。
slugify.config({ replace: [['世界','world'],['你好','hello']] });

指令使用

需要用该功能的地方,在表单元素增加该指令即可。


指令使用

总结

以上就是实现全过程,如果有更好的实现方法,请留言告诉我哦~

上一篇 下一篇

猜你喜欢

热点阅读