vue 项目给输入框增加trim()方法

375 阅读1分钟

我们经常遇到项目写完了,产品突然要求一些修改全局功能的事情。比如:整个平台需要换肤;菜单需要加权限控制;输入框需要去掉前后输入的空格等。

这不,最近做的项目要验收了,甲方突然要求全局的输入框需要去掉前后输入的空格。显然,一个个去改写完的代码比较费劲。有没有更好的快捷些的方案呢?

方案:

1、在模板使用指令(最简单)

  • 在需要的输入上加 v-trim(支持 a-input):
<a-input v-trim v-model="form.xxx" />

或 

<input v-trim v-model="xxx" />
  • 为了兼容 a-input 内部异步渲染的 input,把指令改得更稳一些(插入与更新都尝试绑定):
    Vue.directive('trim', {
      bind(el) {
        el.addEventListener('blur', function(e) {
          // 去除前后空格
          e.target.value = e.target.value.trim();
        });
      }
    });
  • 给所有的 <input> 元素添加这个指令,一个更合适的方法是使用 Vue 的 nextTick 和 mounted 钩子,确保所有的 <input> 元素都已经被渲染和挂载。然后创建一个全局混入(Mixin),在每个页面的组件中使用它。
Vue.mixin({
  mounted() {
    this.$nextTick(() => {
      // 使用 querySelectorAll 获取当前组件内所有的 input 元素,并应用 v-trim 指令
      this.$el.querySelectorAll('input').forEach(input => {
        Vue.directive('trim').bind(input);
      });
    });
  }
});

2、全局捕获 blur(无需在模板写 v-trim,对异步节点同样有效)

  • 在 main.js 添加一次性全局监听(放在创建 Vue 实例之前或之后都可):
document.addEventListener('blur', (e) => {
    const t = e.target;
    if (!t) return;
    const isTextInput = (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA');
    if (!isTextInput || t.type === 'password') return;
    const oldValue = t.value;
    const newValue = typeof oldValue === 'string' ? oldValue.trim() : oldValue;
    if (newValue !== oldValue) {
      	t.value = newValue;
      	t.dispatchEvent(new Event('input', { bubbles: true }));
    }
}, true);

注意

  • 如有不希望被裁剪的特例,需要在逻辑中额外过滤。