<input type="number">
で数値のみの入力にすることはできますが、正負を表す+
や-
、少数を表す.
、べき乗を表すe
が入力できてしまいます。
これらをVueのディレクティブを使って一括で正の整数のみ入力できるようにします。
plugins/integer.directive.ts
import Vue from 'vue';
const targets = ['+', '-', '.', 'e'];
const listen = (element: HTMLInputElement) => {
element.addEventListener('keydown', event => {
if (targets.includes(event.key)) {
event.preventDefault();
}
});
// コピペ対策
element.addEventListener('input', event => {
let value = (event.target as any).value as string;
targets.forEach(char => (value = value.replaceAll(char, '')));
(event.target as any).value = value;
});
};
/**
* v-integer
*
* inputタグにて、正の整数のみを許容する
*/
Vue.directive('integer', {
bind(el, _binding, _vnode) {
if (el instanceof HTMLInputElement) {
listen(el);
} else {
const elements = el.getElementsByTagName('input');
if (elements.length) listen(elements[0]);
}
},
});
input
イベントでreplaceしているのは、コピペした場合にkeydownでは弾けないので追加してます。
ただ、+1234
みたいに先頭に+がある数値をコピペするとevent.target.value
で1234
と+
なしの値が設定されていました。。。
そんなことやるやつはまれだと思うので今回は無視しますが、解決できるのであれば解決しておきたいですね。
test.vue
<template>
<input v-integer type="number">
</template>
nuxt.config.js
plugins: [
'~/plugins/integer.directive.ts',