88 lines
2.0 KiB
Vue
88 lines
2.0 KiB
Vue
<template>
|
|
<div class="" v-bind="$attrs">
|
|
<q-input v-model.number="numValue" type="number" :label="displayName" label-color="primary" stack-label bottom-slots
|
|
:min="min"
|
|
:max="max"
|
|
:rules="rulesExp"
|
|
>
|
|
<template v-slot:hint>
|
|
{{ placeholder }}
|
|
</template>
|
|
</q-input>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { computed, defineComponent, ref, watchEffect } from 'vue';
|
|
export default defineComponent({
|
|
name: 'NumInput',
|
|
inheritAttrs:false,
|
|
components: {
|
|
},
|
|
props: {
|
|
displayName: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
name: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
hint: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
min:{
|
|
type:Number,
|
|
default:undefined
|
|
},
|
|
max:{
|
|
type:Number,
|
|
default:undefined
|
|
},
|
|
//[val=>!!val ||'数値を入力してください',val=>val<=100 && val>=1 || '1-100の範囲内の数値を入力してください']
|
|
rules:{
|
|
type:String,
|
|
default:undefined
|
|
},
|
|
modelValue: {
|
|
type: [Number , String],
|
|
default: undefined
|
|
},
|
|
},
|
|
|
|
setup(props, { emit }) {
|
|
const numValue = ref(props.modelValue);
|
|
const rulesExp = props.rules===undefined?null : eval(props.rules);
|
|
const isError = computed(()=>{
|
|
const val = numValue.value;
|
|
if (val === undefined) {
|
|
return false;
|
|
}
|
|
const numVal = typeof val === "string" ? parseInt(val) : val;
|
|
// Ensure parsed value is a valid number
|
|
if (isNaN(numVal)) {
|
|
return true;
|
|
}
|
|
// Check against min and max boundaries, if defined
|
|
if ((props.min !== undefined && numVal < props.min) || (props.max !== undefined && numVal > props.max)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
|
|
watchEffect(()=>{
|
|
emit("update:modelValue",numValue.value);
|
|
});
|
|
return {
|
|
numValue,
|
|
rulesExp
|
|
};
|
|
}
|
|
});
|
|
</script>
|