feat: convert number input component to composition API

This commit is contained in:
IchliebedichZhu 2024-03-09 21:01:30 +00:00
parent af2e8b389b
commit e91acafde7

View File

@ -13,11 +13,26 @@
</div> --> </div> -->
<div v-if="type === 'simple'"> <div v-if="type === 'simple'">
<span class="prepend">{{ prepend }}</span> <span class="prepend">{{ prepend }}</span>
<input :class="{ 'small-input': true, disable: !editable }" type="text" :value="modelValue" :readonly="editable ? false : 'readonly'" @input="updateValue($event.target.value)" @focus="focusInput" @blur="blurInput" @keyup="verifyNumber" @keydown="(e) => opNumber(e)" /> <input
:class="{ 'small-input': true, disable: !editable }" type="text" :value="modelValue"
:readonly="!props.editable"
@input="updateValue($event && $event.target ? ($event.target as HTMLInputElement).value : '')"
@focus="focusInput"
@blur="blurInput"
@keyup="verifyNumber"
@keydown="(e) => opNumber(e)" />
</div> </div>
<div v-else class="number-input2"> <div v-else class="number-input2">
<div class="input-wrap" @click="edit"> <div class="input-wrap">
<input :class="{ 'real-input': true, disable: !editable }" type="text" :value="modelValue" :readonly="editable ? false : 'readonly'" @input="updateValue($event.target.value)" @focus="focusInput" @blur="blurInput" @keyup="verifyNumber" @keydown="(e) => opNumber(e)" /> <input
:class="{ 'real-input': true, disable: !editable }"
type="text" :value="modelValue" :readonly="!props.editable"
@input="updateValue($event && $event.target ? ($event.target as HTMLInputElement).value : '')"
@focus="focusInput"
@blur="blurInput"
@keyup="verifyNumber"
@keydown="(e) => opNumber(e)"
/>
</div> </div>
<span style="color: rgba(0, 0, 0, 0.45)">{{ label }}</span> <span style="color: rgba(0, 0, 0, 0.45)">{{ label }}</span>
<!-- <div :class="{ 'input-wrap': true, active: inputBorder }"> <!-- <div :class="{ 'input-wrap': true, active: inputBorder }">
@ -30,125 +45,130 @@
</div> </div>
</template> </template>
<script> <script lang="ts" setup>
import { onMounted, ref, watch } from 'vue'
// //
const NAME = 'number-input' // const NAME = 'number-input'
export default { type TProps = {
name: NAME, label?: string
props: { modelValue?: string | number
label: { editable?: boolean
default: '', step?: number
}, maxValue?: string | number
modelValue: { minValue?: string | number
default: '', type?: string
}, prepend?: string
editable: { }
default: true,
}, type TEmits = {
step: { (event: 'finish', data: number | string): void
default: 1, (event: 'update:modelValue', data: number | string): void
}, }
maxValue: {},
minValue: {}, const props = withDefaults(defineProps<TProps>(), {
type: {}, label: '',
prepend: {}, modelValue: '',
}, editable: true,
emits: ['finish', 'update:modelValue'], step: 1
data() { })
return {
inputBorder: false, const emit = defineEmits<TEmits>()
tagText: '',
showEdit: false, const inputBorder = ref<boolean>(false)
const tagText = ref<string | number>('')
const showEdit = ref<boolean>(false)
watch(
() => props.modelValue,
() => fixedNum()
)
onMounted(() => {
fixedNum()
})
function fixedNum() {
//
const decimal = String(props.modelValue).split('.')[1]
if (decimal && decimal.length > 2) {
setTimeout(() => {
updateValue(Number(props.modelValue).toFixed(2))
}, 10)
}
//
if (props.maxValue && props.modelValue > props.maxValue) {
setTimeout(() => {
updateValue(Number(props.maxValue))
}, 10)
} else if (typeof props.minValue === 'number' && Number(props.modelValue) < Number(props.minValue)) {
setTimeout(() => {
updateValue(Number(props.minValue))
}, 10)
}
}
function updateValue(value: string | number) {
emit('update:modelValue', value === '-' ? '-' : Number(value))
}
function up() {
updateValue(parseInt(`${props.modelValue}` ?? '0', 10) + props.step)
}
function down() {
let value = parseInt(`${props.modelValue}` ?? '0', 10) - props.step
updateValue(value)
}
function opNumber(e: KeyboardEvent) {
e.stopPropagation()
switch (e.keyCode) {
case 38:
up()
return
case 40:
down()
return
}
}
function verifyNumber() {
let value = String(props.modelValue)
let len = value.length
let newValue = ''
let isNegative = value[0] === '-'
// 0
for (let i = isNegative ? 1 : 0; i < len; ++i) {
let c = value[i]
if (c == '.' || (c >= '0' && c <= '9')) {
newValue += c
} else {
break
} }
}, }
computed: {}, if (newValue === '') {
watch: { newValue = '0'
modelValue() { }
this.fixedNum() if (isNegative) {
}, newValue = '-' + (newValue === '0' ? '' : newValue)
}, }
mounted() { updateValue(newValue)
this.fixedNum() // this.updateValue(parseInt(newValue, 10))
}, }
methods: {
fixedNum() { function focusInput() {
// inputBorder.value = true
const decimal = String(this.modelValue).split('.')[1] tagText.value = props.modelValue
if (decimal && decimal.length > 2) { }
setTimeout(() => {
this.updateValue(Number(this.modelValue).toFixed(2)) function blurInput() {
}, 10) if (props.modelValue === '-') {
} updateValue(0)
// }
if (this.maxValue && this.modelValue > this.maxValue) { inputBorder.value = false
setTimeout(() => { if (props.modelValue !== tagText.value) {
this.updateValue(Number(this.maxValue)) emit('finish', props.modelValue)
}, 10) }
} else if (typeof this.minValue === 'number' && this.modelValue < this.minValue) {
setTimeout(() => {
this.updateValue(Number(this.minValue))
}, 10)
}
},
updateValue(value) {
this.$emit('update:modelValue', value === '-' ? '-' : Number(value))
},
up() {
this.updateValue(parseInt(this.modelValue || 0, 10) + this.step)
},
down() {
let value = parseInt(this.modelValue || 0, 10) - this.step
this.updateValue(value)
},
opNumber(e) {
e.stopPropagation()
switch (e.keyCode) {
case 38:
this.up()
return
case 40:
this.down()
return
}
},
verifyNumber() {
let value = String(this.modelValue)
let len = value.length
let newValue = ''
let isNegative = value[0] === '-'
// 0
for (let i = isNegative ? 1 : 0; i < len; ++i) {
let c = value[i]
if (c == '.' || (c >= '0' && c <= '9')) {
newValue += c
} else {
break
}
}
if (newValue === '') {
newValue = '0'
}
if (isNegative) {
newValue = '-' + (newValue === '0' ? '' : newValue)
}
this.updateValue(newValue)
// this.updateValue(parseInt(newValue, 10))
},
focusInput() {
this.inputBorder = true
this.tagText = this.modelValue
},
blurInput() {
if (this.modelValue === '-') {
this.updateValue(0)
}
this.inputBorder = false
if (this.modelValue !== this.tagText) {
this.$emit('finish', this.modelValue)
}
},
},
} }
</script> </script>