はじめに
Vuetifyのv-text-filedで最大値、最小値の2つを下記のようなルールで入力させたいときの方法です。
いろいろな実現方法あると思いますが、一つの方法として参考になればと思います。
注意:最大値、最小値の上限下限が決まっている場合に有効な方法です。(だと思います)
入力制限ルール:
- 最大値入力欄には、最小値未満の値を入れられない
- 最小値入力欄には、最大値未満の値を入れられない
イメージ
- 初期状態
- 最小値のみ入力
- 最大値のみ入力
- ルール違反時
コード
<template>
<v-row align="center">
<v-col cols="5">
<v-text-field
class="inputValue"
v-model.number="inputMin"
:rules="[rules.min(inputMax, inputMin)]"
label="数値を入力"
type="number"
@focusout="focusout('min')"
/>
</v-col>
<v-col cols="2" class="text-center"><span>~</span></v-col>
<v-col cols="5">
<v-text-field
class="inputValue"
v-model.number="inputMax"
:rules="[rules.max(inputMin, inputMax)]"
label="数値を入力"
type="number"
@focusout="focusout('max')"
/>
</v-col>
</v-row>
</template>
<script>
export default {
components: {
},
props: [
],
data () {
return {
inputMin: null,
inputMax: null,
INPUT_MIN_VALUE: 0,
INPUT_MAX_VALUE: 10000,
rules: {
min: (max, v) => {
const _max = max === null? this.INPUT_MAX_VALUE: max // maxが未設定(null)の場合は適当に大きな数字を設定可能な最大値に設定
return v <= _max || `最大値 よりも小さい値を設定してください`;
},
max: (min, v) => {
if (v === null) return true // 最大値未入力の場合そのままtrueを返す
const _min = min === null? this.INPUT_MIN_VALUE: min // minが未設定(null)の場合は0を設定可能な最小値に設定
return v >= _min || `最小値 よりも大きい値を設定してください`;
}
}
}
},
computed: {
},
watch: {
},
methods: {
focusout (type) {
// v-text-filedはフォーカスを当てて、何も入力しないでフォーカスを外すと空文字("")がv-modelの中に入るので、その対応
// (もっとスマートなロジックにしたい)
const targetVal = type === 'min'? this.inputMin: this.inputMax
if ((typeof targetVal) === 'string') {
switch(type) {
case 'min':
this.inputMin = null
break
case 'max':
this.inputMax = null
break
default
break
}
}
}
}
}
</script>
<style scoped>
.inputValue >>> input[type="number"] {
-moz-appearance: textfield;
}
.inputValue >>> input::-webkit-outer-spin-button,
.inputValue >>> input::-webkit-inner-spin-button {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
}
</style>
おわりに
ある程度のテストはしていますが、簡単に作ったものなので、入力パターンによっては不具合があるかもしれません。