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 工厂函数
// ...
}
}