mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-28 04:10:31 +08:00
feat: convert number input component to composition API
This commit is contained in:
parent
af2e8b389b
commit
e91acafde7
@ -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>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user