实现 vue3 正整数输入框组件

1.实现代码

components/InputInteger.vue

<!-- 正整数输入框 -->
<template>
  <el-input v-model="_value" @input="onInput" maxlength="9" clearable />
</template>

<script lang="ts" setup>
import { ref } from "vue";

const props = withDefaults(
  defineProps<{
    modelValue?: number | string;
    min?: number;
    max?: number;
  }>(),
  {
    min: 1
  }
);
const emit = defineEmits(["update:modelValue"]);

const _value = ref(props.modelValue);

const onInput = (val: string | undefined) => {
  const result = verifyValue(val); // 拦截输入,进行校验
  _value.value = result;
  emit("update:modelValue", result);
};

const verifyValue = (value: string | undefined): number | string | undefined => {
  const { max, min } = props;
  let result = value;
  let newVal = Number(value);
  if (isNil(value) || Number.isNaN(newVal) || hasDot(value)) {
    return props.modelValue; // 保持输入前的数值
  }
  if (value === "") {
    return undefined;
  }
  if (max && newVal > max) {
    result = String(max);
  }
  if (min && newVal < min) {
    result = String(min);
  }
  return result;
};

// 判断null或undefined
const isNil = (value: any) => {
  return value == null;
};

// 判断是否包含.字符
const hasDot = (value: any) => {
  return String(value).includes(".");
};
</script>

2.全局引入

main.ts

const app = createApp(App);

app.config.errorHandler = errorHandler;

// register the global component
app.component("InputInteger", InputInteger);

3.TS类型声明

src/typings/global-components.d.ts

/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Read more: https://github.com/vuejs/core/pull/3399
export {};

declare module "vue" {
  export interface GlobalComponents {
    InputInteger: (typeof import("../components/InputInteger.vue"))["default"];
  }
}

4. 配置 JSX/TSX 类型推断

参考:https://cn.vuejs.org/guide/extras/render-function.html#jsx-type-inference

tsconfig.json

{
  "compilerOptions": {
    "jsx": "preserve",
    "jsxImportSource": "vue" // 指定了 TypeScript 编译 JSX 时应该从哪个库(vue/react)导入 JSX 工厂函数
    // ...
  }
}
posted @ 2024-09-13 11:15  Better-HTQ  阅读(59)  评论(0编辑  收藏  举报