107 lines
2.0 KiB
Vue
107 lines
2.0 KiB
Vue
<template>
|
|
<div style="width: 100%">
|
|
<el-input-number style="width: 100%"
|
|
v-bind="$attrs"
|
|
:value="displayValue"
|
|
@input="onInput"
|
|
@change="onChange"
|
|
@blur="onBlur"
|
|
@focus="onFocus"
|
|
>
|
|
<slot/>
|
|
</el-input-number>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import {isNumberStr} from "@/utils";
|
|
|
|
export default {
|
|
name: "TaxRateInput",
|
|
|
|
props: {
|
|
// 父组件实际值(未放大的值),例如 0.01
|
|
value: {
|
|
type: [Number, String],
|
|
default: ""
|
|
},
|
|
|
|
// 显示值 : 实际值 = ratio : 1
|
|
ratio: {
|
|
type: Number,
|
|
default: 100
|
|
},
|
|
|
|
// 显示值的小数位精度,比如 2 表示显示保留两位小数
|
|
precision: {
|
|
type: Number,
|
|
default: 4
|
|
}
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
innerDisplayValue: "" // 用户看到的值(已按比例放大)
|
|
};
|
|
},
|
|
|
|
watch: {
|
|
value: {
|
|
immediate: true,
|
|
handler(newVal) {
|
|
this.innerDisplayValue = this.formatDisplay(newVal);
|
|
}
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
displayValue() {
|
|
return this.innerDisplayValue;
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
// 将实际值转换为显示值
|
|
formatDisplay(val) {
|
|
if (val === null || val === "" || isNaN(val) ) return "";
|
|
// 按精度格式化
|
|
return this.$calc.mul(val, this.ratio);
|
|
},
|
|
|
|
// 将显示值转换为实际值
|
|
parseActual(val) {
|
|
if (val === null || val === "" || isNaN(val)) return "";
|
|
|
|
let num = this.$calc.div(val, this.ratio, 4);
|
|
|
|
// 输出给父组件时默认保留更高精度
|
|
return num;
|
|
},
|
|
|
|
|
|
// 用户输入
|
|
onInput(val) {
|
|
this.innerDisplayValue = val;
|
|
|
|
const actual = this.parseActual(val);
|
|
this.$emit("input", actual);
|
|
},
|
|
|
|
// change 事件透传
|
|
onChange(val) {
|
|
const actual = this.parseActual(val);
|
|
console.log()
|
|
this.$emit("change", actual);
|
|
},
|
|
|
|
// 原生事件保留
|
|
onBlur(e) {
|
|
this.$emit("blur", e);
|
|
},
|
|
onFocus(e) {
|
|
this.$emit("focus", e);
|
|
}
|
|
}
|
|
};
|
|
</script>
|