<s-inputNumber v-model="height" tip="请输入您的身高" :precision="2" :min="0" :max="3" :step="0.01"/>
data() { return { height: null, } },
s-inputNumber 组件
默认只能输入整数 事件触发顺序:input change blur <template> <div style="display: flex"> <input class="s-inputNumber" :disabled="disabled" :value="myValue" :placeholder="tip" @input="input($event)" @blur="blur($event)" @change="change($event)" > <div v-if="controls && !disabled" class="controlBox"> <div class="controlBnt" @click="increase"> <i class='iconfont icon-icon12' style="font-size: 12px"></i> </div> <div class="controlBnt" @click="decrease"> <i class='iconfont icon-icon11' style="font-size: 12px"></i> </div> </div> </div> </template> <script> // js精准计算——两个浮点数求和 function accAdd(num1, num2) { var r1, r2, m; try { r1 = num1.toString().split('.')[1].length; } catch (e) { r1 = 0; } try { r2 = num2.toString().split(".")[1].length; } catch (e) { r2 = 0; } m = Math.pow(10, Math.max(r1, r2)); return Math.round(num1 * m + num2 * m) / m; } // js精准计算——两个浮点数相减 function accSub(num1, num2) { var r1, r2, m, n; try { r1 = num1.toString().split('.')[1].length; } catch (e) { r1 = 0; } try { r2 = num2.toString().split(".")[1].length; } catch (e) { r2 = 0; } m = Math.pow(10, Math.max(r1, r2)); n = (r1 >= r2) ? r1 : r2; return (Math.round(num1 * m - num2 * m) / m).toFixed(n); } export default { name: "s-inputNumber", props: { value: {}, step: { type: Number, default: 1 }, max: { type: Number, default: Infinity }, min: { type: Number, default: -Infinity }, disabled: Boolean, controls: { type: Boolean, default: true }, tip: String, precision: { type: Number, validator(val) { return val >= 0 && val === parseInt(val, 10); }, default: 0 } }, computed: { myValue() { let val = this.value === null ? '' : this.value.toString() // 清除"数字"和"."以及"-"以外的字符 val = val.replace(/[^\-\d.]/g, '') // 只保留第一个“点”号, 清除多余的 const idx = val.indexOf('.') if (!(idx === -1 || idx === val.length - 1)) { val = val.substr(0, idx) + '.' + val.substr(idx + 1).replace(/\./g, '') } // 第一个字符如果是.号,则补充前缀0 val = val.replace(/^\./g, '0.') // 只保留首位的负号, 清除多余的 if (val.length > 1) { val = val.charAt(0) + val.substr(1).replace(/-/g, '') } // 将 '-.' 替换成 '-0.' val = val.replace(/^\./g, '0.').replace(/^-\./, '-0.') const str = '^(\\-)*(\\d+)\\.(\\d{' + this.precision + '}).*$' const reg = new RegExp(str) if (this.precision === 0) { // 不需要小数点 val = val.replace(reg, '$1$2') } else { // 通过正则保留小数点后指定的位数 val = val.replace(reg, '$1$2.$3') } this.$emit('input', val) return val } }, methods: { increase() { let val = Number(this.value) val = accAdd(val, this.step) if (val < this.min) { val = this.min } if (val > this.max) { val = this.max } this.$emit('input', val) }, decrease() { let val = Number(this.value) val = accSub(val, this.step) if (val < this.min) { val = this.min } if (val > this.max) { val = this.max } this.$emit('input', val) }, blur($event) { let val = Number($event.target.value) // 只输入负号或未输入时,默认显示最小值 if (isNaN(val) || val === '') { val = this.min } if (val < this.min) { val = this.min } if (val > this.max) { val = this.max } this.$emit('input', val) this.$emit('blur', val) }, input($event) { this.$emit('input', $event.target.value) }, change($event) { this.$emit('change', $event.target.value) }, } } </script> <style scoped> .controlBnt { border: 1px solid grey; cursor: pointer; font-size: 12px; } .s-inputNumber { height: 30px; line-height: 30px; text-align: center; } </style>
相关参数