ivue-material-plus
Version:
A high quality UI components Library with Vue.js
1 lines • 19.9 kB
Source Map (JSON)
{"version":3,"file":"index2.mjs","sources":["../../../../../src/components/ivue-input-number/index.vue"],"sourcesContent":["<template>\r\n <div :class=\"wrapperClasses\">\r\n <!-- 上下按钮 -->\r\n <div :class=\"`${prefixCls}-internal--wrapper`\" v-if=\"!controlsOutside\">\r\n <!-- 上按钮 -->\r\n <ivue-button\r\n :class=\"internalUpClasses\"\r\n depressed\r\n :disabled=\"inputDisabled || data.upDisabled\"\r\n @click=\"handleUp()\"\r\n >\r\n <ivue-icon>expand_less</ivue-icon>\r\n </ivue-button>\r\n <!-- 下按钮 -->\r\n <ivue-button\r\n :class=\"internalDownClasses\"\r\n depressed\r\n :disabled=\"inputDisabled || data.downDisabled\"\r\n @click=\"handleDown()\"\r\n >\r\n <ivue-icon>expand_more</ivue-icon>\r\n </ivue-button>\r\n </div>\r\n <!-- 外部减少按钮 -->\r\n <ivue-button\r\n :class=\"outsideDownClasses\"\r\n depressed\r\n :disabled=\"inputDisabled || data.downDisabled\"\r\n @click=\"handleDown()\"\r\n v-if=\"controlsOutside\"\r\n >\r\n <ivue-icon>remove</ivue-icon>\r\n </ivue-button>\r\n <!-- 外部增加按钮 -->\r\n <ivue-button\r\n :class=\"outsideUpClasses\"\r\n depressed\r\n @click=\"handleUp()\"\r\n :disabled=\"inputDisabled || data.upDisabled\"\r\n v-if=\"controlsOutside\"\r\n >\r\n <ivue-icon>add</ivue-icon>\r\n </ivue-button>\r\n <!-- 左右按钮 -->\r\n <!-- 输入框 -->\r\n <div :class=\"`${prefixCls}-input--wrapper`\">\r\n <input\r\n :class=\"`${prefixCls}-input`\"\r\n autocomplete=\"off\"\r\n spellcheck=\"false\"\r\n :disabled=\"inputDisabled\"\r\n :autofocus=\"autofocus\"\r\n :readonly=\"readonly || !editable\"\r\n :name=\"name\"\r\n :placeholder=\"placeholder\"\r\n :value=\"formatterValue\"\r\n :id=\"inputId\"\r\n @focus=\"focus\"\r\n @blur=\"blur\"\r\n @change=\"handleChange\"\r\n @input=\"handleChange\"\r\n @keydown.stop=\"handleKeyDown\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n reactive,\r\n computed,\r\n defineComponent,\r\n nextTick,\r\n watch,\r\n onMounted,\r\n} from 'vue';\r\n\r\nimport IvueIcon from '../ivue-icon';\r\nimport IvueButton from '../ivue-button';\r\n\r\nimport { useFormItem, useFormItemInputId, useDisabled } from '../../hooks';\r\nimport { debugWarn } from '../../utils/error';\r\n\r\n// type\r\nimport type { Props, Data } from './types/input-number';\r\n\r\nconst prefixCls = 'ivue-input-number';\r\n\r\nexport default defineComponent({\r\n name: prefixCls,\r\n emits: ['on-focus', 'on-blur', 'update:modelValue', 'on-change'],\r\n props: {\r\n /**\r\n * 设置禁用状态\r\n *\r\n * @type {Boolean}\r\n */\r\n disabled: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 自动获取焦点\r\n *\r\n * @type {Boolean}\r\n */\r\n autofocus: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 是否设置为只读\r\n *\r\n * @type {Boolean}\r\n */\r\n readonly: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 是否可编辑\r\n *\r\n * @type {Boolean}\r\n */\r\n editable: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n /**\r\n * input name\r\n *\r\n * @type {String}\r\n */\r\n name: {\r\n type: String,\r\n },\r\n /**\r\n * 占位文本\r\n *\r\n * @type {String}\r\n */\r\n placeholder: {\r\n type: String,\r\n default: '',\r\n },\r\n /**\r\n * 指定输入框展示值的格式\r\n *\r\n * @type {Function}\r\n */\r\n formatter: {\r\n type: Function,\r\n },\r\n /**\r\n * 数值精度, 小数点\r\n *\r\n * @type {Number}\r\n */\r\n precision: {\r\n type: Number,\r\n },\r\n /**\r\n * modelValue\r\n *\r\n * @type {Number}\r\n */\r\n modelValue: {\r\n type: Number,\r\n default: 1,\r\n },\r\n /**\r\n * 是否实时响应数据,设置为 false 时,只会在失焦时更改数据\r\n *\r\n * @type {Boolean}\r\n */\r\n activeChange: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n /**\r\n * 指定从 formatter 里转换回数字的方式,和 formatter 搭配使用\r\n *\r\n * @type {Function}\r\n */\r\n parser: {\r\n type: Function,\r\n },\r\n /**\r\n * 最大值\r\n *\r\n * @type {Number}\r\n */\r\n max: {\r\n type: Number,\r\n default: Infinity,\r\n },\r\n /**\r\n * 最小值\r\n *\r\n * @type {Number}\r\n */\r\n min: {\r\n type: Number,\r\n default: -Infinity,\r\n },\r\n /**\r\n * 按钮位置是否置于两侧\r\n *\r\n * @type {Boolean}\r\n */\r\n controlsOutside: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 每次改变的步伐,可以是小数\r\n *\r\n * @type {Number}\r\n */\r\n step: {\r\n type: Number,\r\n default: 1,\r\n },\r\n /**\r\n * id\r\n *\r\n * @type {String}\r\n */\r\n id: {\r\n type: String,\r\n },\r\n /**\r\n * 输入时是否触发表单的校验\r\n *\r\n * @type {Boolean}\r\n */\r\n validateEvent: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n },\r\n setup(props: Props, { emit }) {\r\n // 设置表单对应的输入框id\r\n const { formItem } = useFormItem();\r\n\r\n // 输入框id\r\n const { inputId } = useFormItemInputId(props, {\r\n formItemContext: formItem,\r\n });\r\n\r\n // 输入框禁用\r\n const inputDisabled = useDisabled();\r\n\r\n // data\r\n const data = reactive<Data>({\r\n /**\r\n * 获取焦点\r\n *\r\n * @type {Number}\r\n */\r\n focused: false,\r\n /**\r\n * 当前value\r\n *\r\n * @type {Number}\r\n */\r\n currentValue: props.modelValue,\r\n /**\r\n * 增加禁用\r\n *\r\n * @type {Boolean}\r\n */\r\n upDisabled: false,\r\n /**\r\n * 减少禁用\r\n *\r\n * @type {Boolean}\r\n */\r\n downDisabled: false,\r\n });\r\n\r\n // computed\r\n\r\n // 外层样式\r\n const wrapperClasses = computed(() => {\r\n return [\r\n prefixCls,\r\n {\r\n // 获取焦点\r\n [`${prefixCls}-focused`]: data.focused,\r\n // 禁用\r\n [`${prefixCls}-disabled`]: inputDisabled.value,\r\n // 按钮位置是否置于两侧\r\n [`${prefixCls}-controls-outside`]: props.controlsOutside,\r\n },\r\n ];\r\n });\r\n\r\n // 数值精度格式化\r\n const precisionValue = computed(() => {\r\n // 没有值\r\n if (!data.currentValue) {\r\n return data.currentValue;\r\n }\r\n\r\n return props.precision\r\n ? data.currentValue.toFixed(props.precision)\r\n : data.currentValue;\r\n });\r\n\r\n // 输入框value\r\n const formatterValue = computed(() => {\r\n if (props.formatter && precisionValue.value !== null) {\r\n return props.formatter(precisionValue.value);\r\n } else {\r\n return precisionValue.value;\r\n }\r\n });\r\n\r\n // 内部上按钮\r\n const internalUpClasses = computed(() => {\r\n return [\r\n `${prefixCls}-internal`,\r\n {\r\n [`${prefixCls}-internal--disabled`]: data.upDisabled,\r\n },\r\n ];\r\n });\r\n\r\n // 内部下按钮\r\n const internalDownClasses = computed(() => {\r\n return [\r\n `${prefixCls}-internal`,\r\n {\r\n [`${prefixCls}-internal--disabled`]: data.downDisabled,\r\n },\r\n ];\r\n });\r\n\r\n // 外部上按钮\r\n const outsideUpClasses = computed(() => {\r\n return [\r\n `${prefixCls}-outside`,\r\n `${prefixCls}-outside--up`,\r\n {\r\n [`${prefixCls}-internal--disabled`]: data.upDisabled,\r\n },\r\n ];\r\n });\r\n\r\n // 外部下按钮\r\n const outsideDownClasses = computed(() => {\r\n return [\r\n `${prefixCls}-outside`,\r\n `${prefixCls}-outside--down`,\r\n\r\n {\r\n [`${prefixCls}-internal--disabled`]: data.downDisabled,\r\n },\r\n ];\r\n });\r\n\r\n // methods\r\n\r\n // 获取焦点\r\n const focus = (event: Event) => {\r\n data.focused = true;\r\n\r\n emit('on-focus', event);\r\n };\r\n\r\n // 失去焦点\r\n const blur = () => {\r\n data.focused = false;\r\n\r\n emit('on-blur');\r\n };\r\n\r\n // 改变值\r\n const handleChange = (event: Event) => {\r\n // change 失焦时更改数据\r\n if (event.type === 'change' && props.activeChange) {\r\n return;\r\n }\r\n\r\n // input 是否实时响应数据\r\n if (event.type === 'input' && !props.activeChange) {\r\n return;\r\n }\r\n\r\n const target = event.target as HTMLInputElement;\r\n\r\n let value: string = target.value.trim();\r\n\r\n // 指定从 formatter 里转换回数字的方式,和 formatter 搭配使用\r\n if (props.parser) {\r\n value = props.parser(value);\r\n }\r\n\r\n // 是空字符串\r\n const isEmptyString = value.length === 0;\r\n\r\n // 是空字符串\r\n if (isEmptyString) {\r\n setInputValue(null);\r\n\r\n return;\r\n }\r\n\r\n // prevent fire early if decimal. If no more input the change event will fire later\r\n // 是否是十进制 -> 用于 -号\r\n if (event.type === 'input' && value.match(/^-?\\.?$|\\.$/)) {\r\n return;\r\n }\r\n\r\n // 转换类型\r\n const _value = Number(value);\r\n\r\n // 不是NaN\r\n if (!isNaN(_value)) {\r\n data.currentValue = _value;\r\n\r\n setInputValue(_value);\r\n }\r\n // 返回当前value\r\n else {\r\n target.value = `${data.currentValue}`;\r\n }\r\n };\r\n\r\n // 设置输入框value\r\n const setInputValue = (value: null | number) => {\r\n // 如果 step 是小数,且没有设置 precision\r\n if (value && !isNaN(props.precision)) {\r\n value = Number(Number(value).toFixed(props.precision));\r\n }\r\n\r\n const { min, max } = props;\r\n\r\n // 有值\r\n if (value !== null) {\r\n // 大于最大值\r\n if (value > max) {\r\n value = max;\r\n }\r\n // 小于最小值\r\n else if (value < min) {\r\n value = min;\r\n }\r\n }\r\n\r\n nextTick(() => {\r\n // 当前value\r\n data.currentValue = value;\r\n\r\n // modelValue\r\n emit('update:modelValue', value);\r\n\r\n // 数值改变时的回调,返回当前值\r\n emit('on-change', value);\r\n });\r\n };\r\n\r\n // 修改value\r\n const changeValue = (value: number) => {\r\n const _value = Number(value);\r\n\r\n // 判断是否有值\r\n if (!isNaN(_value)) {\r\n // 大于最大值\r\n data.upDisabled = _value + props.step > props.max;\r\n\r\n // 小于最小值\r\n data.downDisabled = _value - props.step < props.min;\r\n }\r\n // 都禁用\r\n else {\r\n data.upDisabled = true;\r\n data.downDisabled = true;\r\n }\r\n };\r\n\r\n // 增加\r\n const handleUp = (event?: Event) => {\r\n changeStep('up', event);\r\n };\r\n\r\n // 减少\r\n const handleDown = (event?: Event) => {\r\n changeStep('down', event);\r\n };\r\n\r\n // 改变步骤\r\n const changeStep = (type: string, event?) => {\r\n // 禁用\r\n if (inputDisabled.value || props.readonly) {\r\n return false;\r\n }\r\n\r\n let value = Number(data.currentValue);\r\n\r\n // 每次改变的步伐,可以是小数\r\n const step = Number(props.step);\r\n\r\n // NaN\r\n if (isNaN(value)) {\r\n return false;\r\n }\r\n\r\n // 输入一个数字,然后向上或向下键\r\n if (event) {\r\n // 当前的 value\r\n const targetVal = Number(event.target.value);\r\n\r\n if (!isNaN(targetVal)) {\r\n if (type === 'up') {\r\n // 小于最大值\r\n if (addNum(targetVal, step) <= props.max) {\r\n value = targetVal;\r\n }\r\n // 大于最大值\r\n else {\r\n return false;\r\n }\r\n } else if (type === 'down') {\r\n // 大于最小值\r\n if (addNum(targetVal, -step) >= props.min) {\r\n value = targetVal;\r\n }\r\n // 小于最小值\r\n else {\r\n return false;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // 增加\r\n if (type === 'up') {\r\n value = addNum(value, step);\r\n }\r\n // 减少\r\n else if (type === 'down') {\r\n value = addNum(value, -step);\r\n }\r\n\r\n // 设置输入框value\r\n setInputValue(value);\r\n };\r\n\r\n // 增加数字\r\n const addNum = (num1: number, num2: number): number => {\r\n let sq1: number;\r\n let sq2: number;\r\n\r\n try {\r\n // 有多少位小数\r\n sq1 = num1.toString().split('.')[1].length;\r\n } catch (e) {\r\n sq1 = 0;\r\n }\r\n\r\n try {\r\n // 有多少位小数\r\n sq2 = num2.toString().split('.')[1].length;\r\n } catch (e) {\r\n sq2 = 0;\r\n }\r\n\r\n // 需要除多是位小数\r\n const m = Math.pow(10, Math.max(sq1, sq2));\r\n\r\n // 步骤 -> 转换为整数\r\n const step = Math.round(num2 * m);\r\n\r\n // 当前值 -> 转换为整数\r\n const currentValue = Math.round(num1 * m);\r\n\r\n // 当前值 + 步骤 / 需要除多是位小数\r\n return (currentValue + step) / m;\r\n };\r\n\r\n // 键盘点击\r\n const handleKeyDown = (event) => {\r\n // 增加\r\n if (event.keyCode === 38) {\r\n event.preventDefault();\r\n\r\n handleUp(event);\r\n }\r\n // 减少\r\n else if (event.keyCode === 40) {\r\n event.preventDefault();\r\n\r\n handleDown(event);\r\n }\r\n };\r\n\r\n // onMounted\r\n onMounted(() => {\r\n changeValue(data.currentValue);\r\n });\r\n\r\n // watch\r\n\r\n // 监听 modelValue\r\n watch(\r\n () => props.modelValue,\r\n (value) => {\r\n data.currentValue = value;\r\n\r\n // 输入时是否触发表单的校验\r\n if (props.validateEvent) {\r\n formItem?.validate?.('change').catch((err) => debugWarn(err));\r\n }\r\n }\r\n );\r\n\r\n // 监听 currentValue\r\n watch(\r\n () => data.currentValue,\r\n (value) => {\r\n changeValue(value);\r\n }\r\n );\r\n\r\n // 监听 最小值\r\n watch(\r\n () => props.min,\r\n () => {\r\n changeValue(data.currentValue);\r\n }\r\n );\r\n\r\n // 监听 最大值\r\n watch(\r\n () => props.max,\r\n () => {\r\n changeValue(data.currentValue);\r\n }\r\n );\r\n\r\n return {\r\n prefixCls,\r\n\r\n // data\r\n data,\r\n inputId,\r\n inputDisabled,\r\n\r\n // computed\r\n wrapperClasses,\r\n formatterValue,\r\n internalUpClasses,\r\n internalDownClasses,\r\n outsideUpClasses,\r\n outsideDownClasses,\r\n\r\n // methods\r\n focus,\r\n blur,\r\n handleChange,\r\n handleUp,\r\n handleDown,\r\n handleKeyDown,\r\n };\r\n },\r\n components: {\r\n IvueIcon,\r\n IvueButton,\r\n },\r\n});\r\n</script>\r\n"],"names":["_resolveComponent","_normalizeClass","_createCommentVNode","_openBlock","_createVNode","_withCtx","_createElementVNode"],"mappings":"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"}