【问题记录】el-input-number组件数值null显示为0的解决方案

问题记录

对于使用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>

执行效果如下:
【问题记录】el-input-number组件数值null显示为0的解决方案_第1张图片

从上图可以看到,在执行表单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 时,会对valueNumber(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

执行效果如下:
【问题记录】el-input-number组件数值null显示为0的解决方案_第2张图片
至此问题就全部解决。
欢迎大家收藏⭐或者点赞,也欢迎在评论区进行交流。



扩展阅读:
  • 详解在React项目中集成Redux
  • 常用的几款Vue移动端UI推荐
  • el-table行拖拽排序效果的实现(基于sortablejs)

你可能感兴趣的:(vue,前端,ElementUI,vue.js,前端,elementui)