指尖上的记忆指尖上的记忆
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub

vue3下input框限制只允许输入数字和小数:

export const filterInvalidCharacters = (value: string): string => {
  const reg = /[^0-9.]/g;
  return value.replaceAll(reg, "");
};

[^0-9.]:表示匹配所有不是数字(0-9)和小数点(.)的字符。
replaceAll:将所有匹配的非法字符替换为空字符,从而实现过滤。

但是这个还有问题,就是如果使用中文输入法,比如搜狗,在windows操作系统下,还是可以输入汉字,以及拼音。解决办法就是加一个 @compositionend 事件

实际使用:
const handleInteger = (event: InputEvent) => {
  const currentValue = (event.target as HTMLInputElement).value || "";

  const filterValue = filterInvalidCharacters(currentValue);
  if (filterValue === currentValue) {
    const currentNumberValue = Number(currentValue) || 0;
    if (props.maxNumber && currentNumberValue > props.maxNumber) {
      (event.target as HTMLInputElement).value = lastInputValue.value;
      model.value = lastInputValue.value;
      event.preventDefault();
    }
  } else {
    event.preventDefault();
    model.value = filterValue;
  }
};


const handleInput = (event: InputEvent) => {
  const currentValue = (event.target as HTMLInputElement).value || "";

  const filterValue = filterInvalidCharacters(currentValue);
  if (filterValue !== currentValue) {
    event.preventDefault();
    model.value = filterValue;
  }

  if (currentValue.includes(".")) {
    const numbersAfterDecimalPoint = currentValue.split(".")[1];
    if (numbersAfterDecimalPoint.length > props.decimalPlaces) {
      (event.target as HTMLInputElement).value = lastInputValue.value;
      model.value = lastInputValue.value;
      event.preventDefault();
    }
  }
};


<MInput
  v-model="model as string | number"
  outlined
  hide-state-icons
  type="text"
  :name
  :label
  :disabled
  :placeholder
  :hint="field?.errorMessage.value || hint"
  :state
  :class="dynamicClasses"
  :autocomplete
  @keydown="handleKeyDown($event)"
  @keyup.enter="emit('enter')"
  @input="onlyInteger ? handleInteger($event) : handleInput($event)"
  @compositionend="onlyInteger ? handleInteger($event) : handleInput($event)"
/>


@compositionend 是什么?
@compositionend 是 Vue 绑定的 compositionend 事件,它在 输入法(IME)输入完成后 触发,通常用于处理拼音输入、日语假名输入等情况。
作用:
用于监听输入法输入完成的时机
防止输入法候选字符未完全提交时触发 @input
解决 @input 在部分输入法(如 Windows 下的搜狗输入法)中的兼容性问题


为什么 @compositionend 很重要?
在 Windows 系统(特别是中文输入法)中:

用户在输入 "你好" 时,输入法会先输入 n,然后 i,但这时输入框内的值 还未最终确定,候选框还在变化。
直到用户按下 空格或回车,才会提交最终的「你好」。
但 @input 可能会在未完成拼写时触发,导致错误的处理。
在 Linux/macOS 上,一些输入法在输入过程中不会触发 @input,导致字符无法正确过滤。

为了解决这个问题,我们可以监听 compositionend 事件,在输入法输入完成后再进行处理。