| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- <template>
- <view :class="classes" :style="{ height: pxCheck(buttonSize) }">
- <nut-icon
- name="minus"
- class="nut-inputnumber__icon"
- :class="{ 'nut-inputnumber__icon--disabled': !reduceAllow() }"
- :size="buttonSize"
- @click="reduce"
- >
- </nut-icon>
- <view v-if="readonly" class="nut-inputnumber__text--readonly">
- {{ modelValue }}
- </view>
- <input
- v-else
- type="number"
- :min="min"
- :max="max"
- :style="{ width: pxCheck(inputWidth) }"
- :disabled="disabled"
- :readonly="readonly"
- :value="modelValue"
- @input="change"
- @blur="blur"
- @focus="focus"
- />
- <nut-icon
- name="plus"
- class="nut-inputnumber__icon"
- :class="{ 'nut-inputnumber__icon--disabled': !addAllow() }"
- :size="buttonSize"
- @click="add"
- >
- </nut-icon>
- </view>
- </template>
- <script lang="ts">
- import { computed } from 'vue';
- import { createComponent } from '../../utils/create';
- import { pxCheck } from '../../utils/pxCheck';
- const { componentName, create } = createComponent('inputnumber');
- export default create({
- props: {
- modelValue: {
- type: [Number, String],
- default: 0
- },
- inputWidth: {
- type: [Number, String],
- default: ''
- },
- buttonSize: {
- type: [Number, String],
- default: ''
- },
- min: {
- type: [Number, String],
- default: 1
- },
- max: {
- type: [Number, String],
- default: 9999
- },
- step: {
- type: [Number, String],
- default: 1
- },
- decimalPlaces: {
- type: [Number, String],
- default: 0
- },
- disabled: {
- type: Boolean,
- default: false
- },
- readonly: {
- type: Boolean,
- default: false
- }
- },
- emits: ['update:modelValue', 'change', 'blur', 'focus', 'reduce', 'add', 'overlimit'],
- setup(props, { emit }) {
- const classes = computed(() => {
- const prefixCls = componentName;
- return {
- [prefixCls]: true,
- [`${prefixCls}--disabled`]: props.disabled
- };
- });
- const fixedDecimalPlaces = (v: string | number): string => {
- return Number(v).toFixed(Number(props.decimalPlaces));
- };
- const change = (event: Event) => {
- const input = event.target as HTMLInputElement;
- emit('update:modelValue', input.value, event);
- };
- const emitChange = (value: string | number, event: Event) => {
- let output_value: number | string = fixedDecimalPlaces(value);
- emit('update:modelValue', output_value, event);
- emit('change', output_value, event);
- };
- const addAllow = (value = Number(props.modelValue)): boolean => {
- return value < Number(props.max) && !props.disabled;
- };
- const reduceAllow = (value = Number(props.modelValue)): boolean => {
- return value > Number(props.min) && !props.disabled;
- };
- const reduce = (event: Event) => {
- emit('reduce', event);
- if (reduceAllow()) {
- let output_value = Number(props.modelValue) - Number(props.step);
- emitChange(output_value, event);
- } else {
- emit('overlimit', event, 'reduce');
- }
- };
- const add = (event: Event) => {
- emit('add', event);
- if (addAllow()) {
- let output_value = Number(props.modelValue) + Number(props.step);
- emitChange(output_value, event);
- } else {
- emit('overlimit', event, 'add');
- }
- };
- const blur = (event: Event) => {
- if (props.disabled) return;
- if (props.readonly) return;
- const input = event.target as HTMLInputElement;
- let value = +input.value;
- if (value < Number(props.min)) {
- value = Number(props.min);
- } else if (value > Number(props.max)) {
- value = Number(props.max);
- }
- emitChange(value, event);
- emit('blur', event);
- };
- const focus = (event: Event) => {
- if (props.disabled) return;
- if (props.readonly) {
- blur(event);
- return;
- }
- emit('focus', event);
- };
- return {
- classes,
- change,
- blur,
- focus,
- add,
- addAllow,
- reduce,
- reduceAllow,
- pxCheck
- };
- }
- });
- </script>
|