el-form 利用validator自定义校验规则(座机号验证,手机号验证,身份证号验证,邮箱验证,IP验证)

316 阅读3分钟

image.png

电话

/**
     * 宽泛验证,不区分座机还是手机号,限制只能输入数字和-
     * @param rule 
     * @param value 
     * @param callback
     */
    var checkPhoneNumber = (rule, value, callback) => {
      const v = /^[0-9-]+$/.test(value)
      if (!v) {
        callback(new Error('请输入正确的电话格式!'))
      } else {
        callback()
      }
    }

座机号

  /**
     * 判断是否为座机号
     * @param rule
     * @param tel
     * @param callback
     */
    const checkLandlineNumber = (rule, tel, callback) => {
      // 1.区号部分为3或4位数字
      // 2.中间用连字符-连接
      // 3.本地号码为7或8位数字
      // 4.支持分机号,可选,如0571-88776655-9527
      const myreg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/
      if ((tel === callback) === undefined) {
        return myreg.test(rule)
      }
      if (rule.required) {
        if (myreg.test(tel)) {
          callback()
        } else {
          callback(new Error('请输入有效的电话号码'))
        }
      } else {
        if (!(tel !== '' && tel != null && tel !== 'undefined')) {
          callback()
        } else {
          if (myreg.test(tel)) {
            callback()
          } else {
            callback(new Error('请输入有效的电话号码'))
          }
        }
      }
    }

手机号

 /**
     * 判断是否为手机号
     * 首位必须为1+总长度11位+只能输入数字
     * @param rule
     * @param phone
     * @param callback
     */
    const checkMobileNumber = (rule, phone, callback) => {
      const myreg = /^1[0-9]{10}$/
      if ((phone === callback) === undefined) {
        return myreg.test(rule)
      }
      if (rule.required) {
        if (myreg.test(phone)) {
          callback()
        } else {
          callback(new Error('请输入有效的手机号码'))
        }
      } else {
        if (!(phone !== '' && phone != null && phone !== 'undefined')) {
          callback()
        } else {
          if (myreg.test(phone)) {
            callback()
          } else {
            callback(new Error('请输入有效的手机号码'))
          }
        }
      }
    }

身份证号

   /**
     * 判断是否为身份证号
     * @param rule
     * @param value
     * @param callback
     */
    const checkIDCard = (rule, value, callback) => {
      if ((value === callback) === undefined) {
        value = rule
      }
      // 加权因子
      const weight_factor = [
        7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
      ]
      // 校验码
      const check_code = [
        '1',
        '0',
        'X',
        '9',
        '8',
        '7',
        '6',
        '5',
        '4',
        '3',
        '2'
      ]

      const code = value + ''
      if (value !== null && value !== undefined) {
        var last = value[17] // 最后一个
      }
      const seventeen = code.substring(0, 17)

      // ISO 7064:1983.MOD 11-2
      // 判断最后一位校验码是否正确
      const arr = seventeen.split('')
      const len = arr.length
      let num = 0
      for (let i = 0; i < len; i++) {
        num = num + arr[i] * weight_factor[i]
      }

      // 获取余数
      const resisue = num % 11
      const last_no = check_code[resisue]

      // 格式的正则
      // 正则思路
      // 第一位不可能是0
      // 第二位到第六位可以是0-9
      // 第七位到第十位是年份,所以七八位为19或者20
      // 十一位和十二位是月份,这两位是01-12之间的数值
      // 十三位和十四位是日期,是从01-31之间的数值
      // 十五,十六,十七都是数字0-9
      // 十八位可能是数字0-9,也可能是X

      const idcard_patter =
        /^[1-9][0-9]{5}([1][9][0-9]{2}|[2][0][0|1][0-9])([0][1-9]|[1][0|1|2])([0][1-9]|[1|2][0-9]|[3][0|1])[0-9]{3}([0-9]|[X])$/

      // 判断格式是否正确
      const format = idcard_patter.test(value)

      if ((value === callback) === undefined) {
        return last === last_no && format
      }
      // 返回验证结果,校验码和格式同时正确才算是合法的身份证号码
      if (rule.required) {
        if (last === last_no && format) {
          callback()
        } else {
          callback(new Error('请输入有效的身份证号'))
        }
      } else {
        if (!(value !== '' && value != null && value !== 'undefined')) {
          callback()
        } else {
          if (!(last === last_no && format)) {
            callback(new Error('请输入有效的身份证号'))
          } else {
            callback()
          }
        }
      }
    }

邮箱

 /**
     * 验证邮箱格式是否正确
     * @param rule
     * @param email
     * @param callback
     */
    const checkEmail = (rule, email, callback) => {
      const reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
      if ((email === callback) === undefined) {
        return reg.test(rule)
      }
      if (rule.required) {
        if (reg.test(email)) {
          callback()
        } else {
          callback(new Error('请输入有效的邮箱'))
        }
      } else {
        if (!(email !== '' && email != null && email !== 'undefined')) {
          callback()
        } else {
          if (reg.test(email)) {
            callback()
          } else {
            callback(new Error('请输入有效的邮箱'))
          }
        }
      }
    }

IP

    /**
     * 验证ip格式是否合法
     * @param rule
     * @param value
     * @param callback
     */
    const checkIP = (rule, value, callback) => {
      if (value === '' || value === undefined || value == null) {
        callback(new Error('请输入内容'))
      } else {
        const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
        if ((!reg.test(value)) && value !== '') {
          callback(new Error('请输入有效的IP地址'))
        } else {
          callback()
        }
      }
    }

完整代码

<template>
  <div class="main">
    <span class="title">表单格式验证</span>
    <el-form
      ref="ruleForm"
      :model="ruleForm"
      :rules="rules"
      label-width="300px"
    >
      <el-form-item label="电话(限制只能输入数字和-)" prop="phoneNumber">
        <el-input v-model="ruleForm.phoneNumber" />
      </el-form-item>
      <el-form-item label="座机号" prop="landlineNumber">
        <el-input v-model="ruleForm.landlineNumber" />
      </el-form-item>
      <el-form-item label="手机号" prop="mobileNumber">
        <el-input v-model="ruleForm.mobileNumber" />
      </el-form-item>
      <el-form-item label="身份证号" prop="idcard">
        <el-input v-model="ruleForm.idcard" />
      </el-form-item>
      <el-form-item label="邮箱" prop="email">
        <el-input v-model="ruleForm.email" />
      </el-form-item>
      <el-form-item label="IP" prop="ip">
        <el-input v-model="ruleForm.ip" />
      </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: 'Example03Basic',
  components: {},
  data() {
    /**
     * 宽泛验证,不区分座机还是手机号,限制只能输入数字和-
     * @param rule
     * @param value
     * @param callback
     */
    var checkPhoneNumber = (rule, value, callback) => {
      const v = /^[0-9-]+$/.test(value)
      if (!v) {
        callback(new Error('请输入正确的电话格式!'))
      } else {
        callback()
      }
    }

    /**
     * 判断是否为座机号
     * @param rule
     * @param tel
     * @param callback
     */
    const checkLandlineNumber = (rule, tel, callback) => {
      // 1.区号部分为3或4位数字
      // 2.中间用连字符-连接
      // 3.本地号码为7或8位数字
      // 4.支持分机号,可选,如0571-88776655-9527
      const myreg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/
      if ((tel === callback) === undefined) {
        return myreg.test(rule)
      }
      if (rule.required) {
        if (myreg.test(tel)) {
          callback()
        } else {
          callback(new Error('请输入有效的电话号码'))
        }
      } else {
        if (!(tel !== '' && tel != null && tel !== 'undefined')) {
          callback()
        } else {
          if (myreg.test(tel)) {
            callback()
          } else {
            callback(new Error('请输入有效的电话号码'))
          }
        }
      }
    }

    /**
     * 判断是否为手机号
     * 首位必须为1+总长度11位+只能输入数字
     * @param rule
     * @param phone
     * @param callback
     */
    const checkMobileNumber = (rule, phone, callback) => {
      const myreg = /^1[0-9]{10}$/
      if ((phone === callback) === undefined) {
        return myreg.test(rule)
      }
      if (rule.required) {
        if (myreg.test(phone)) {
          callback()
        } else {
          callback(new Error('请输入有效的手机号码'))
        }
      } else {
        if (!(phone !== '' && phone != null && phone !== 'undefined')) {
          callback()
        } else {
          if (myreg.test(phone)) {
            callback()
          } else {
            callback(new Error('请输入有效的手机号码'))
          }
        }
      }
    }

    /**
     * 判断是否为身份证号
     * @param rule
     * @param value
     * @param callback
     */
    const checkIDCard = (rule, value, callback) => {
      if ((value === callback) === undefined) {
        value = rule
      }
      // 加权因子
      const weight_factor = [
        7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2
      ]
      // 校验码
      const check_code = [
        '1',
        '0',
        'X',
        '9',
        '8',
        '7',
        '6',
        '5',
        '4',
        '3',
        '2'
      ]

      const code = value + ''
      if (value !== null && value !== undefined) {
        var last = value[17] // 最后一个
      }
      const seventeen = code.substring(0, 17)

      // ISO 7064:1983.MOD 11-2
      // 判断最后一位校验码是否正确
      const arr = seventeen.split('')
      const len = arr.length
      let num = 0
      for (let i = 0; i < len; i++) {
        num = num + arr[i] * weight_factor[i]
      }

      // 获取余数
      const resisue = num % 11
      const last_no = check_code[resisue]

      // 格式的正则
      // 正则思路
      // 第一位不可能是0
      // 第二位到第六位可以是0-9
      // 第七位到第十位是年份,所以七八位为19或者20
      // 十一位和十二位是月份,这两位是01-12之间的数值
      // 十三位和十四位是日期,是从01-31之间的数值
      // 十五,十六,十七都是数字0-9
      // 十八位可能是数字0-9,也可能是X

      const idcard_patter =
        /^[1-9][0-9]{5}([1][9][0-9]{2}|[2][0][0|1][0-9])([0][1-9]|[1][0|1|2])([0][1-9]|[1|2][0-9]|[3][0|1])[0-9]{3}([0-9]|[X])$/

      // 判断格式是否正确
      const format = idcard_patter.test(value)

      if ((value === callback) === undefined) {
        return last === last_no && format
      }
      // 返回验证结果,校验码和格式同时正确才算是合法的身份证号码
      if (rule.required) {
        if (last === last_no && format) {
          callback()
        } else {
          callback(new Error('请输入有效的身份证号'))
        }
      } else {
        if (!(value !== '' && value != null && value !== 'undefined')) {
          callback()
        } else {
          if (!(last === last_no && format)) {
            callback(new Error('请输入有效的身份证号'))
          } else {
            callback()
          }
        }
      }
    }

    /**
     * 验证邮箱格式是否正确
     * @param rule
     * @param email
     * @param callback
     */
    const checkEmail = (rule, email, callback) => {
      const reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
      if ((email === callback) === undefined) {
        return reg.test(rule)
      }
      if (rule.required) {
        if (reg.test(email)) {
          callback()
        } else {
          callback(new Error('请输入有效的邮箱'))
        }
      } else {
        if (!(email !== '' && email != null && email !== 'undefined')) {
          callback()
        } else {
          if (reg.test(email)) {
            callback()
          } else {
            callback(new Error('请输入有效的邮箱'))
          }
        }
      }
    }

    /**
     * 验证ip格式是否合法
     * @param rule
     * @param value
     * @param callback
     */
    const checkIP = (rule, value, callback) => {
      if (value === '' || value === undefined || value == null) {
        callback(new Error('请输入内容'))
      } else {
        const reg =
          /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
        if (!reg.test(value) && value !== '') {
          callback(new Error('请输入有效的IP地址'))
        } else {
          callback()
        }
      }
    }

    return {
      ruleForm: {
        phoneNumber: '',
        landlineNumber: '',
        mobileNumber: '',
        idcard: '',
        email: '',
        ip: ''
      },
      rules: {
        phoneNumber: [
          {
            required: true,
            message: '请输入电话',
            trigger: ['change', 'blur']
          },
          {
            validator: checkPhoneNumber,
            message: '请输入有效的电话',
            trigger: ['blur', 'change']
          }
        ],
        landlineNumber: [
          {
            required: true,
            validator: checkLandlineNumber,
            trigger: ['blur', 'change']
          }
        ],
        mobileNumber: [
          {
            required: true,
            validator: checkMobileNumber,
            trigger: ['blur', 'change']
          }
        ],
        idcard: [
          {
            required: true,
            validator: checkIDCard,
            trigger: ['blur', 'change']
          }
        ],
        email: [
          {
            required: true,
            validator: checkEmail,
            trigger: ['blur', 'change']
          }
        ],
        ip: [
          {
            required: true,
            validator: checkIP,
            trigger: ['blur', 'change']
          }
        ]
      }
    }
  },
  mounted() {},

  methods: {
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert('submit!')
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetForm(formName) {
      this.$refs[formName].resetFields()
    }
  }
}
</script>

<style lang="scss" scoped>
.main {
  padding: 2%;
}
.title {
  font-weight: bold;
  padding: 0 0 0 12px;
  border-left: 4px solid;
  border-left-color: #409eff;
}
.el-form {
  margin-top: 20px;
}
.text {
  width: 50%;
  padding: 1% 1% 1% 15%;
}
</style>