新版本 el-input 不支持 v-model.trim,自定义指令去除首尾空格

发布时间 2023-11-17 15:52:03作者: shayloyuki

问题场景

<el-input type="textarea" v-model.trim="value" /> 多行文本输入框无法换行。

经测试,去掉 .trim 修饰符后,就可正常换行了。

官网文档 ,发现 element-ui 新版本不支持 v-model 修饰符。

image

因此,若在新版本的 element-uiel-input 中使用 v-model.trim ,会发生以下问题:

  1. 无论在文本的前、中、后,都无法输入空格;
  2. type 为 textarea 时,无法换行。

解决

不使用 v-model.trim 怎样去掉输入内容首尾的空格?

有两种方案:

  1. 提交数据时,手动执行 .trim()
  2. (推荐)封装自定义指令 v-trim

为了便于后续开发,推荐方案二。

directives/trim/index.js
// 获取元素
function getInput(el) {
  let inputEle;
  if (el.tagName !== "INPUT") {
    // 若 el-input 中 type 为 textarea
    if (el._prevClass.includes("el-textarea")) {
      inputEle = el.querySelector("textarea");
    } else {
      inputEle = el.querySelector("input");
    }
  } else {
    inputEle = el;
  }
  return inputEle;
}

// 创建自定义事件
function dispatchEvent(el, type) {
  const evt = new Event(type);
  el.dispatchEvent(evt);

  // 以下为过时的方法,已被废弃
  // let evt = document.createEvent("HTMLEvents");
  // evt.initEvent(type, true, true);
  // el.dispatchEvent(evt);
}

const Trim = {
  inserted: (el) => {
    let inputEle = getInput(el);
    const handler = function (event) {
      const newVal = event.target.value.trim();
      if (event.target.value !== newVal) {
        event.target.value = newVal;
        dispatchEvent(inputEle, "input");
      }
    };
    el.inputEle = inputEle;
    el._blurHandler = handler;
    // 事件监听
    inputEle.addEventListener("blur", handler);
  },
  unbind(el) {
    const { inputEle } = el;
    inputEle.removeEventListener("blur", el._blurHandler);
  },
};
export default Trim;
directive/index.js
import trim from "./trim/index";

const install = function (Vue) {
  Vue.directive("trim", trim);
};

if (window.Vue) {
  window["trim"] = trim;
  Vue.use(install); // eslint-disable-line
}

export default install;

使用时给 el-input 加上 v-trim 即可。

注意

编辑器会提示 initEvent() 初始化事件已被废弃,如下所示:

image

因此,使用 new Event 代替。

参考链接

  1. el-input类型为textarea时不能使用v-model.trim
  2. vue2 利用自定义指令全局去除el-input框前后空格
  3. vue3自定义全局指令(过滤前后空格,输入框自动聚焦、点击复制文本到粘贴板)
  4. new Event 创建自定义事件
  5. event.initEvent 已过时