前言

经常是一个input表单需要输入数字和小数,那么如果仅仅是要求数据格式,我们可以通过表单校验的方式对输入的值进行限制,具体的做法,我之前就写过文章:《element input表单验证数字类型方法大全》

里面有关于数字类型校验的方式,基本涵盖了日常需求。

但是,仅仅就只能这样吗???

no,如果后端要求你输入的数字,提交给他的时候也必须是数字类型呢?

要知道,即便我们做了表单校验,校验它输入的必须是数字格式,但是input本身就是一个string类型的值,即便你设置type="number"也无法改变它值的类型。

有人说用.number;其实这个问题之前就聊过了,这个修饰符只能处理整形数字,小数是做不了的。

所以今天来谈谈怎么搞定这个转换。

做法

<template>
  <el-form :model="form" :rules="rules" ref="ruleForm" label-width="120px" size="medium">
    <el-form-item label="产品折扣:" prop="discount">
      <el-input v-model="form.discount" placeholder="请输入产品折扣">
        <template slot="append">%</template>
      </el-input>
    </el-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
         form: {
           discount:"", //产品折扣
         },
         rules: {
           discount: [
             {
               required: true,
                type: "number",
                min: 0,
                max: 100,
                message: "请输入0-100的数字",
                trigger: "blur",
                transform(value) {
                   return value !== "" ? Number(value) : "";
                }
             }
           ]
         }
      }
    }
  
  }
</script>

这是一个根据我之前教程写的,用于校验数字的例子,由于需要必填,所以对空字符要做单独处理,因为空字符被Number转换后事0;0也是数字,必填就无效了,所以单独处理。

但是这样会有一个问题,我们form里面的discount还是字符的格式,transform并不会改变源值。

市面上的方法(除了自定义指令),我都测过了,不行,那么我们只有一条路可走:在合适的时机修改源值

在合适的时机修改源值

我的做法是在transform里面修改,因为我本身在校验的时候就做了类型转换,为啥还要在转一次呢,是吧。

那么,我们就需要在transform中拿到form,简单点就直接通过this呗。

于是:

<template>
  <el-form :model="form" :rules="rules" ref="ruleForm" label-width="120px" size="medium">
    <el-form-item label="产品折扣:" prop="discount">
      <el-input v-model="form.discount" placeholder="请输入产品折扣">
        <template slot="append">%</template>
      </el-input>
    </el-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      const transform = (key)=>{
         return {
            required: true,
            type: "number",
            min: 0,
            max: 100,
            message: "请输入0-100的数字",
            trigger: "blur",
            transform: (value)=> {
              const newValue = value !== "" ? Number(value) : "";
              if (Number.isFinite(newValue)) {
                this.form[key] = newValue;
              }
              return newValue;
            }
         }
      }
      return {
         form: {
           discount:"", //产品折扣
         },
         rules: {
           discount: [transform("discount")]
         }
      }
    }
  
  }
</script>

通过箭头函数拿到this,然后判断下,如果是有限数字,那么就赋值,测试了下,效果不错。

而且自己二次开发一下也可以

优化

仔细品读一下发现最重要的是this上下文,而且如果把配置丢在data上面,感觉很不美观,而且,复用不方便,于是乎:

<template>
  <el-form :model="form" :rules="rules" ref="ruleForm" label-width="120px" size="medium">
    <el-form-item label="产品折扣:" prop="discount">
      <el-input v-model="form.discount" placeholder="请输入产品折扣">
        <template slot="append">%</template>
      </el-input>
    </el-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      const transform = (data) => data;
      return {
         form: {
           discount:"", //产品折扣
         },
         rules: {
           discount: [
             transform({
              required: true,
              type: "number",
              min: 0,
              max: 100,
              message: "请输入0-100的数字",
              trigger: "blur",
              transform: (value)=> {
                const newValue = value !== "" ? Number(value) : "";
                if (Number.isFinite(newValue)) {
                  this.form[key] = newValue;
                }
                return newValue;
              }
             })
           ]
         }
      }
    }
  
  }
</script>

这种方式,利用函数作用域的概念,将校验对象的作用域改变,从而拿到this,从写法上更加灵活,但是复用性就相对差一些。

分类: vue 项目实战 标签: numbervueelement表单校验数字类型

评论

暂无评论数据

暂无评论数据

目录