问题记录
对于使用ElementUI组件的用户来说,其中的el-input-number
组件有一个不太友好的点(也可称之为feature)就是当数值为null
时,el-input-number
组件显示的数值会转换为0
,如果组件设置了必填项required: true
,进行表单验证时,是可以正常通过验证的。
测试代码如下:
<template>
<div class="hello">
Form1:
<el-form
:model="formData"
:rules="rules"
ref="ruleForm"
label-width="100px"
>
<el-form-item label="数值" prop="number">
<el-input-number
v-model="formData.number"
:controls="false"
></el-input-number>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">
提交
</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "Form1",
data() {
return {
formData: {
number: "",
},
rules: {
number: [
{ required: true, message: "请输入", trigger: ["change", "blur"] },
],
},
};
},
methods: {
getData() {
return new Promise((resolve, reject) => {
resolve({ number: null });
});
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// alert("submit!");
this.$message({
message: `validate success. number value: ${this.formData.number}`,
type: "success",
});
} else {
console.log("error submit!!");
this.$message.error("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
},
mounted() {
this.getData().then((data) => {
this.formData = data;
});
},
};
</script>
执行效果如下:
从上图可以看到,在执行表单validate
操作后,验证是能正常通过必填项验证的,并且从上图的message,我们会发现数值竟然变成了0
,这对于部分用户来说确是有点不方便,因为在一些情况下,我们需要保持数值为null
,并不需要转化成0
。
原因
去翻阅ElementUI的Github库(地址:https://github.com/ElemeFE/element),查阅packages/input-number下的源码,我们可以发现有如下源码,具体源码链接如下:https://github.com/ElemeFE/element/blob/dev/packages/input-number/src/input-number.vue#L114-L141
watch: {
value: {
immediate: true,
handler(value) {
let newVal = value === undefined ? value : Number(value);
if (newVal !== undefined) {
if (isNaN(newVal)) {
return;
}
if (this.stepStrictly) {
const stepPrecision = this.getPrecision(this.step);
const precisionFactor = Math.pow(10, stepPrecision);
newVal = Math.round(newVal / this.step) * precisionFactor * this.step / precisionFactor;
}
if (this.precision !== undefined) {
newVal = this.toPrecision(newVal, this.precision);
}
}
if (newVal >= this.max) newVal = this.max;
if (newVal <= this.min) newVal = this.min;
this.currentValue = newVal;
this.userInput = null;
this.$emit('input', newVal);
}
}
},
请注意着重看这一行代码:
let newVal = value === undefined ? value : Number(value);
当value
不为undefined
时,会对value
做Number(value)
处理,而Number('')
和Number(null)
的执行结果都是0
,所以el-input-number
组件绑定的值,如果为空(''
)或者null
,则过统一转化为0
。
解决方案
知道原因后,解决起来也很简单,如果期望el-input-number
组件数值为空(''
)或者null
,不通过必填验证,则只需要将其赋值成undefined
即可,代码如下:
<template>
<div class="hello">
Form2:
<el-form
:model="formData"
:rules="rules"
ref="ruleForm"
label-width="100px"
>
<el-form-item label="数值" prop="number">
<el-input-number
v-model="formData.number"
:controls="false"
></el-input-number>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">
提交
</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "Form2",
data() {
return {
formData: {
number: "",
},
rules: {
number: [
{ required: true, message: "请输入", trigger: ["change", "blur"] },
],
},
};
},
methods: {
getData() {
return new Promise((resolve, reject) => {
resolve({ number: null });
});
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// alert("submit!");
this.$message({
message: `validate success. number value: ${this.formData.number}`,
type: "success",
});
} else {
console.log("error submit!!");
this.$message.error("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
},
mounted() {
this.getData().then((data) => {
data.number = data.number || undefined; // 如果是null或者空,则转化为undefined
this.formData = data;
});
},
};
</script>
上述代码其中有一行如下代码,是将数据中的空(''
)或者null
,转化为undefined
。
data.number = data.number || undefined; // 如果是null或者空,则转化为undefined
执行效果如下:
至此问题就全部解决。😄
欢迎大家收藏⭐或者点赞👍,也欢迎在评论区进行交流。
扩展阅读: