
<template>
<div class="number-range-input" ref="rangeInputRef">
<div class="input-wrap" :style="{ width: inputWidth }">
<el-input
v-model="innerMin"
placeholder="最小值"
@blur="handleSyncValue"
@input="handleMinInput"
@clear="handleSyncValue"
:clearable="clearable"
type="number"
style="width: calc(50% - 6px);"
size="mini"
:disabled="disabled"
></el-input>
<span class="separator">-</span>
<el-input
v-model="innerMax"
placeholder="最大值"
@blur="handleSyncValue"
@input="handleMaxInput"
@clear="handleSyncValue"
:clearable="clearable"
type="number"
style="width: calc(50% - 6px);"
size="mini"
:disabled="disabled"
></el-input>
</div>
</div>
</template>
<script>
export default {
name: 'NumberRangeInput',
props: {
value: {
type: String,
default: ''
},
inputWidth: {
type: String,
default: '300px'
},
clearable: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
},
rangeTip: {
type: String,
default: '最小值不能大於最大值'
}
},
data() {
return {
innerMin: '',
innerMax: ''
};
},
watch: {
value: {
immediate: true,
handler(val) {
if (!val || typeof val !== 'string') {
this.innerMin = '';
this.innerMax = '';
return;
}
const [minStr, maxStr] = val.split('&&').map(item => item.trim());
const minNum = Number(minStr);
const maxNum = Number(maxStr);
if (!isNaN(minNum) && !isNaN(maxNum) && minStr && maxStr) {
this.innerMin = String(Math.min(minNum, maxNum));
this.innerMax = String(Math.max(minNum, maxNum));
} else {
this.innerMin = '';
this.innerMax = '';
}
}
}
},
methods: {
handleMinInput() {
const { innerMin, innerMax } = this;
if (innerMin && innerMax && !isNaN(Number(innerMin)) && !isNaN(Number(innerMax))) {
const minNum = Number(innerMin);
const maxNum = Number(innerMax);
if (minNum > maxNum) {
this.innerMax = innerMin;
this.$message?.warning(this.rangeTip);
}
}
},
handleMaxInput() {
const { innerMin, innerMax } = this;
if (innerMin!=='' && innerMax!=='' && !isNaN(Number(innerMin)) && !isNaN(Number(innerMax))) {
const minNum = Number(innerMin);
const maxNum = Number(innerMax);
if (maxNum < minNum) {
this.innerMin =innerMax;
this.$message?.warning(this.rangeTip);
}
}
},
handleSyncValue() {
const { innerMin, innerMax } = this;
console.log("innerMin, innerMax ",innerMin, innerMax )
console.log("!isNaN(Number(innerMin) ",isNaN(Number(innerMin)))
console.log("!isNaN(Number(innerMax) ",isNaN(Number(innerMax)))
let result = '';
if (innerMin!=='' && innerMax!=='' && !isNaN(Number(innerMin)) && !isNaN(Number(innerMax))) {
const minNum = Number(innerMin);
const maxNum = Number(innerMax);
const minStr = String(Math.min(minNum, maxNum));
const maxStr = String(Math.max(minNum, maxNum));
result = `${minStr}&&${maxStr}`;
}else{
console.log("不滿足")
}
this.$emit('input', result);
this.$emit('rangeChange', result);
},
validate() {
const { innerMin, innerMax } = this;
return innerMin && innerMax && !isNaN(Number(innerMin)) && !isNaN(Number(innerMax));
},
reset() {
this.innerMin = '';
this.innerMax = '';
this.handleSyncValue();
}
}
};
</script>
<style scoped>
.number-range-input {
width: 100%;
box-sizing: border-box;
}
.input-wrap {
display: flex;
align-items: center;
justify-content: space-between;
}
.separator {
color: #666;
user-select: none;
}
::v-deep .el-input__inner{
height: 28px !important;
line-height: 28px !important;
padding: 0 3px !important;
font-size: 12px !important;
text-align: center;
}
</style>