number.vue 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. <template>
  2. <UIText
  3. class="number ready"
  4. :class="{ ctrl }"
  5. type="number"
  6. :right="right"
  7. :model-value="tempValue"
  8. :placeholder="placeholder"
  9. :other="{ min, max, step }"
  10. :readonly="!inInput"
  11. @update:model-value="updateTempValue"
  12. @blur="blurHandler"
  13. >
  14. <template v-for="(slot, name) in $slots" #[name]="raw">
  15. <slot :name="name" v-bind="raw" />
  16. </template>
  17. <template v-if="ctrl" #icon>
  18. <div class="ctrls">
  19. <UIIcon type="up-a" ctrl class="up" @click="updateModelValue(normValue(modelValue) + step)" />
  20. <UIIcon type="d-r" ctrl class="down" @click="updateModelValue(normValue(modelValue) - step)" />
  21. </div>
  22. </template>
  23. </UIText>
  24. </template>
  25. <script setup lang="ts">
  26. import { defineEmits, defineProps, ref, watchEffect } from 'vue'
  27. import { toRawType } from '@kankan-components/utils'
  28. import UIIcon from '@kankan-components/components/basic/icon'
  29. import UIText from '../text/text.vue'
  30. import { numberProps } from './number'
  31. const emit = defineEmits(['update:modelValue'])
  32. const props = defineProps(numberProps)
  33. const isNumber = raw => !(toRawType(raw) === 'Number' ? Number.isNaN(raw) : Number.isNaN(Number(raw)))
  34. const tempValue = ref(props.modelValue)
  35. watchEffect(() => {
  36. tempValue.value = props.modelValue
  37. })
  38. const updateTempValue = val => {
  39. tempValue.value = val
  40. const tval = Number(val)
  41. if (!Number.isNaN(tval) && tval !== props.modelValue) {
  42. updateModelValue(tval)
  43. }
  44. }
  45. const blurHandler = () => {
  46. tempValue.value = props.modelValue
  47. updateModelValue(props.modelValue)
  48. }
  49. const normValue = (val: number) => {
  50. val = Number(val)
  51. if (Number.isNaN(val)) {
  52. return props.min || 0
  53. } else {
  54. return val
  55. }
  56. }
  57. const updateModelValue = (val: number) => {
  58. val = normValue(val)
  59. if (isNumber(props.min)) {
  60. const min = Number(props.min)
  61. val = val < min ? min : val
  62. }
  63. if (isNumber(props.max)) {
  64. const max = Number(props.max)
  65. val = val > max ? max : val
  66. }
  67. emit('update:modelValue', val)
  68. }
  69. </script>