自定义指令 v-number-only
1. 创建指令文件
src/directives/numberOnly.ts
ts
/**
* 自定义指令
* @description 输入框只允许输入数字
* @example
* <el-input v-model="num" v-number-only placeholder="只能输入数字" />
*/
import type { Directive } from 'vue'
export const numberOnly: Directive<HTMLInputElement> = {
mounted(el) {
const input = el.querySelector('input')!
input.addEventListener('input', () => {
// 使用正则替换掉所有非数字字符
input.value = input.value.replace(/\D/g, '')
// 触发 v-model 更新
input.dispatchEvent(new Event('input'))
})
}
}
2. 注册指令
在 main.ts
中注册全局指令:
ts
import { createApp } from 'vue'
import App from './App.vue'
import { numberOnly } from './directives/numberOnly'
const app = createApp(App)
app.directive('number-only', numberOnly)
app.mount('#app')
3. 使用方式
在任何 el-input
上都可以直接使用:
vue
<template>
<el-input v-model="num" v-number-only placeholder="只能输入数字" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
const num = ref('')
</script>
拓展
支持数字 + 小数点 + 负号
ts
/**
* 数字 + 小数点 + 负号
*/
export const numberWithDecimal: Directive<HTMLInputElement> = {
mounted(el) {
const input = el.querySelector('input')!
input.addEventListener('input', () => {
let val = input.value
// 允许开头负号
val = val.replace(/[^0-9.-]/g, '')
// 只允许一个负号(且必须在开头)
val = val.replace(/(?!^)-/g, '')
// 只允许一个小数点
val = val.replace(/(\..*)\./g, '$1')
input.value = val
input.dispatchEvent(new Event('input'))
})
}
}
支持千分位格式化
ts
/**
* 千分位格式化(只允许数字)
* 输入 1234567 -> 显示 1,234,567
*/
export const numberThousands: Directive<HTMLInputElement> = {
mounted(el) {
const input = el.querySelector('input')!
input.addEventListener('input', () => {
// 去掉所有非数字
let raw = input.value.replace(/\D/g, '')
if (!raw) {
input.value = ''
} else {
// 格式化成千分位
input.value = Number(raw).toLocaleString()
}
input.dispatchEvent(new Event('input'))
})
}
}
只允许输入中文
ts
/**
* 只允许输入中文
*/
export const chineseOnly: Directive<HTMLInputElement> = {
mounted(el) {
const input = el.querySelector('input')!
input.addEventListener('input', () => {
// 过滤掉所有非中文字符(\u4e00-\u9fa5 是中文字符范围)
input.value = input.value.replace(/[^\u4e00-\u9fa5]/g, '')
input.dispatchEvent(new Event('input'))
})
}
}