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,90 +45,95 @@
</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,
},
step: {
default: 1,
},
maxValue: {},
minValue: {},
type: {},
prepend: {},
},
emits: ['finish', 'update:modelValue'],
data() {
return {
inputBorder: false,
tagText: '',
showEdit: false,
} }
},
computed: {}, type TEmits = {
watch: { (event: 'finish', data: number | string): void
modelValue() { (event: 'update:modelValue', data: number | string): void
this.fixedNum() }
},
}, const props = withDefaults(defineProps<TProps>(), {
mounted() { label: '',
this.fixedNum() modelValue: '',
}, editable: true,
methods: { step: 1
fixedNum() { })
const emit = defineEmits<TEmits>()
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(this.modelValue).split('.')[1] const decimal = String(props.modelValue).split('.')[1]
if (decimal && decimal.length > 2) { if (decimal && decimal.length > 2) {
setTimeout(() => { setTimeout(() => {
this.updateValue(Number(this.modelValue).toFixed(2)) updateValue(Number(props.modelValue).toFixed(2))
}, 10) }, 10)
} }
// //
if (this.maxValue && this.modelValue > this.maxValue) { if (props.maxValue && props.modelValue > props.maxValue) {
setTimeout(() => { setTimeout(() => {
this.updateValue(Number(this.maxValue)) updateValue(Number(props.maxValue))
}, 10) }, 10)
} else if (typeof this.minValue === 'number' && this.modelValue < this.minValue) { } else if (typeof props.minValue === 'number' && Number(props.modelValue) < Number(props.minValue)) {
setTimeout(() => { setTimeout(() => {
this.updateValue(Number(this.minValue)) updateValue(Number(props.minValue))
}, 10) }, 10)
} }
}, }
updateValue(value) {
this.$emit('update:modelValue', value === '-' ? '-' : Number(value)) function updateValue(value: string | number) {
}, emit('update:modelValue', value === '-' ? '-' : Number(value))
up() { }
this.updateValue(parseInt(this.modelValue || 0, 10) + this.step)
}, function up() {
down() { updateValue(parseInt(`${props.modelValue}` ?? '0', 10) + props.step)
let value = parseInt(this.modelValue || 0, 10) - this.step }
this.updateValue(value) function down() {
}, let value = parseInt(`${props.modelValue}` ?? '0', 10) - props.step
opNumber(e) { updateValue(value)
}
function opNumber(e: KeyboardEvent) {
e.stopPropagation() e.stopPropagation()
switch (e.keyCode) { switch (e.keyCode) {
case 38: case 38:
this.up() up()
return return
case 40: case 40:
this.down() down()
return return
} }
}, }
verifyNumber() { function verifyNumber() {
let value = String(this.modelValue) let value = String(props.modelValue)
let len = value.length let len = value.length
let newValue = '' let newValue = ''
let isNegative = value[0] === '-' let isNegative = value[0] === '-'
@ -132,23 +152,23 @@ export default {
if (isNegative) { if (isNegative) {
newValue = '-' + (newValue === '0' ? '' : newValue) newValue = '-' + (newValue === '0' ? '' : newValue)
} }
this.updateValue(newValue) updateValue(newValue)
// this.updateValue(parseInt(newValue, 10)) // 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) { function focusInput() {
this.$emit('finish', this.modelValue) inputBorder.value = true
tagText.value = props.modelValue
}
function blurInput() {
if (props.modelValue === '-') {
updateValue(0)
}
inputBorder.value = false
if (props.modelValue !== tagText.value) {
emit('finish', props.modelValue)
} }
},
},
} }
</script> </script>