element 表单注册自动定位到校验失败位置、验证码倒计时

目录

validate 对整个表单进行校验的方法

validator 验证器

validateField 对部分表单字段进行校验的方法

resetFields 对整个表单进行重置

手机验证码倒计时实现

表单注册案例代码


validate 对整个表单进行校验的方法

  • 参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功(返回 boolean 类型)和未通过校验的字段(返回 object 类型)。若不传入回调函数,则会返回一个 promise
submitForm() {
  this.$refs.form.validate(valid, object => {
    if(valid){
      // 当校验通过时,这里写逻辑代码
    } else {
      // 当校验不通过时,这里写逻辑代码
    }
  })
}

validator 验证器

  • 可以为指定字段自定义验证函数 function(rule, value, callback)

validateField 对部分表单字段进行校验的方法

  • 如发送短信验证码之前,校验手机号字段是否正确
sendVerifyCode() {
  this.$refs.form.validateField('phone', (errorMessage) => {
    if(!errorMessage){
      // 当校验通过时,这里写逻辑代码;发送接口请求,验证码按钮进入倒计时状态
    }
  })
}
  •  校验多个字段使用此方法,如校验手机号和密码字段是否正确
sendVerifyCode() {
  this.$refs.form.validateField(['phone', 'pass'], (errorMessage) => {
    if(!errorMessage){
      // 当校验通过时,这里写逻辑代码;发送接口请求,验证码按钮进入倒计时状态
    }
  })
}

resetFields 对整个表单进行重置

  • 将所有字段值重置为初始值并移除校验结果

手机验证码倒计时实现

  • 使用间歇性计时器 setInterval,当时间为 0 时,清空计时器 clearInterval

表单注册案例代码

  • 注:表单校验成功后,再去校验是否已阅读协议;如果已阅读发送接口请求,否则弹出错误提示
  • 按钮上显示加载状态使用 :loading 属性

<template>
  <section>
    <el-form :model="form" label-width="100px" :rules="rules" ref="form" status-icon hide-required-asterisk>
      <el-form-item label="手机号" prop="phone">
        <el-input v-model.number="form.phone" ref="phone" placeholder="请输入手机号" />
      </el-form-item>
      <el-form-item label="短信验证码" prop="verifyCode">
        <div style="display: flex;">
          <el-input v-model.trim="form.verifyCode" ref="verifyCode" placeholder="短信验证码" />
          <el-button type="primary" plain @click="sendVerifyCode" :loading="isLoading" style="margin-left: 10px;">{{btnText}}</el-button>
        </div>  
      </el-form-item>
      <el-form-item label="密码" prop="pass">
        <el-input v-model.trim="form.pass" type="password" ref="pass" show-password placeholder="请输入长度为4-8位包含数字、字母、特殊字符的密码" />
      </el-form-item>
      <el-form-item label="确认密码" prop="checkPass">
        <el-input v-model.trim="form.checkPass" type="password" ref="checkPass" show-password placeholder="确认密码" />
      </el-form-item>
      <el-form-item prop="isReading">
        <el-checkbox v-model="form.isReading" ref="isReading">
          我已阅读并同意<a href="" target="_blank">《服务协议》</a><a href="" target="_blank">《隐私条款》</a>
        </el-checkbox>
      </el-form-item>
      <el-form-item>
        <el-button @click="submitForm" type="primary">注册</el-button>
        <el-button @click="resetForm">重置</el-button>
      </el-form-item>  
    </el-form>
  </section>
</template>

<script>
  export default {
    data(){
      return{
        form: {
          phone: '', // 手机号
          pass: '', // 第一次录入密码
          checkPass: '', // 第二次录入密码
          verifyCode: '', // 验证码
          isReading: false, // 协议是否阅读 
        },
        btnText: '短信验证码', // 短信验证码按钮文字
        time: 6, // 短信验证码时间
        isLoading: false, // 短信验证码按钮是否显示加载中
        rules: {
          phone: [{required: true, validator: this.validatePhone, trigger: 'blur'}],
          pass: [{required: true, validator: this.validatePass, trigger: 'blur'}],
          checkPass: [{required: true, validator: this.validatePass2, trigger: 'blur'}],
          verifyCode: [{required: true, message: '请输入验证码', trigger: 'blur'}],
        }
      }
    },
    methods: {
      submitForm(){
        this.$refs.form.validate((valid, object) => {
          if(valid){
            if(this.form.isReading){
              console.log('submit Form')
              // 逻辑处理发送接口请求
            } else {
              this.$message.error('请阅读并同意相关协议')
            }
          } else {
            for(let key in object){
              let dom = this.$refs[key] // 自动定位到校验失败的位置
              // 滚动到指定节点  
              dom.$el.scrollIntoView({
                block: 'center', // 值有 start、center、end、nearest;当前显示在视图区域中间
                behavior: 'smooth' // 值有 auto、instant、smooth;缓动动画(当前是慢速的),instant(瞬间)
              })
            }
            console.log('error submit')
            return false
          }
        })
      },
      resetForm(){
        this.$refs.form.resetFields() // 重置表单
      },
      validatePhone(rule, value, callback){
        if(value === ''){
          callback('请输入手机号')
        } else {
          const reg = /^((1[3,5,8][0-9])|(14[5,7])|(17[0,5,6,7,8])|(19[7]))\d{8}$/
          if(reg.test(value)){
            callback()
          } else {
            callback('请输入正确的手机号')
          }
        }
      },
      validatePass(rule, value, callback){
        if(value === ''){
          callback('请输入长度为4-8位包含数字、字母、特殊字符的密码')
        } else {
          const reg = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\W_]).{4,8}$/
          if(reg.test(value)){
            callback()
          } else {
            callback('请输入长度为4-8位包含数字、字母、特殊字符的密码')
          } 
        }
      },
      validatePass2(rule, value, callback){
        if(value === ''){
          callback('请再次输入密码')
        } else if(value !== this.form.pass) {
          callback('两次输入密码不一致!')
        } else {
          callback()
        }
      },
      sendVerifyCode(){
        /** validateField 对部分表单字段进行校验的方法 */
        this.$refs.form.validateField('phone', errorMessage => {
          if(!errorMessage){
            // 发送接口请求后按钮进入倒计时状态
            /**
             * 时间开始倒数
             * 按钮进入禁用状态
             * 如果倒计时结束 按钮恢复可用状态 按钮文字变成重新发送 把倒计时时间重置
             * 倒计时的过程中 按钮文字显示为 多少s后重新发送
             */
            let timer = setInterval(() => {
              this.time-- // 时间进入倒计时
              this.btnText = `${this.time}s后重新发送`
              this.isLoading = true // 按钮显示加载中
              console.log(this.time)
              if(this.time === 0){
                 this.btnText = '重新发送'
                 this.time = 6 // 重置时间
                 this.isLoading = false // 重置加载按钮
                 clearInterval(timer)
              }
            }, 1000)
          }
        })
      }
    }
  }
</script>

<style scoped>
  a{
    text-decoration: none;
    color:#409EFF;
  }
</style>

表单注册案例代码优化

  • 注意:此处 dom 节点是一个数组
<template>
  <section>
    <!-- flexLayout 指的是输入框 + 按钮布局 -->
    <el-form :model="form" label-width="100px" :rules="rules" ref="form" status-icon hide-required-asterisk>
      <el-form-item v-for="(item, index) in formList" :key="index" :label="item.label" :prop="item.prop">
         <el-input
          v-if="item.type === 'number'"
          v-model.number="form[item.prop]"
          :ref="item.prop"
          :placeholder="item.placeholder"
        />
        <div v-if="item.type === 'flexLayout'" style="display: flex;">
          <el-input
            v-model.trim="form[item.prop]"
            :ref="item.prop"
            :placeholder="item.placeholder"
          />
          <el-button
            type="primary"
            plain
            style="margin-left: 10px;"
            @click="sendVerifyCode(item.prop)"
            :loading="isLoading"
            :disabled="isDisabled"
          >{{btnText}}</el-button>
        </div>
        <el-input
          v-if="item.type == ('text' && 'textarea' && 'password')"
          v-model.trim="form[item.prop]"
          :ref="item.prop"
          :placeholder="item.placeholder"
          :show-password="item.showPassword"
          :type="item.type === 'password' ? 'password' : 'text' || 'textarea'"
        />
        <el-checkbox v-if="item.type === 'checkbox'" v-model="form[item.prop]" :ref="item.prop">
          我已阅读并同意<a href="" target="_blank">《服务协议》</a><a href="" target="_blank">《隐私条款》</a>
        </el-checkbox>
      </el-form-item>
      <el-form-item>
        <el-button @click="submitForm" type="primary">注册</el-button>
        <el-button @click="resetForm">重置</el-button>
      </el-form-item>  
    </el-form>
  </section>
</template>

<script>
  export default {
    data(){
      return{
        formList: [
          {label: '手机号', prop: 'phone', type: 'number', placeholder: '请输入手机号'},
          {label: '短信验证码', prop: 'verifyCode', type: 'flexLayout', placeholder: '请输入短信验证码'},
          {label: '密码', prop: 'pass', type: 'password', showPassword: true, placeholder: '请输入长度为4-8位包含数字、字母、特殊字符的密码'},
          {label: '确认密码', prop: 'checkPass', type: 'password', showPassword: true, placeholder: '确认密码'},
          {label: '', prop: 'isReading', type: 'checkbox', placeholder: ''},
        ],
        form: {
          phone: '', // 手机号
          verifyCode: '', // 验证码
          pass: '', // 第一次录入密码
          checkPass: '', // 第二次录入密码
          isReading: false, // 协议是否阅读 
        },
        btnText: '短信验证码', // 短信验证码按钮文字
        time: 10, // 短信验证码时间
        isLoading: false, // 短信验证码按钮是否显示加载中
        isDisabled: false, // 短信验证码按钮是否禁用
        rules: {
          phone: [{required: true, validator: this.validatePhone, trigger: 'blur'}],
          pass: [{required: true, validator: this.validatePass, trigger: 'blur'}],
          checkPass: [{required: true, validator: this.validatePass2, trigger: 'blur'}],
          verifyCode: [{required: true, message: '请输入验证码', trigger: 'blur'}],
        }
      }
    },
    methods: {
      submitForm(){
        this.$refs.form.validate((valid, object) => {
          if(valid){
            if(this.form.isReading){
              console.log('submit Form')
              // 逻辑处理发送接口请求
            } else {
              this.$message.error('请阅读并同意相关协议')
            }
          } else {
            for(let key in object){
              let dom = this.$refs[key] // 自动定位到校验失败的位置
              /** 注意此处 dom 节点是一个数组 */
              console.log(key, dom, dom[0].$el)
              // 滚动到指定节点  
              dom[0].$el.scrollIntoView({
                block: 'center', // 值有 start、center、end、nearest;当前显示在视图区域中间
                behavior: 'smooth' // 值有 auto、instant、smooth;缓动动画(当前是慢速的),instant(瞬间)
              })
            }
            console.log('error submit')
            return false
          }
        })
      },
      resetForm(){
        this.$refs.form.resetFields() // 重置表单
      },
      validatePhone(rule, value, callback){
        if(value === ''){
          callback('请输入手机号')
        } else {
          const reg = /^((1[3,5,8][0-9])|(14[5,7])|(17[0,5,6,7,8])|(19[7]))\d{8}$/
          if(reg.test(value)){
            callback()
          } else {
            callback('请输入正确的手机号')
          }
        }
      },
      validatePass(rule, value, callback){
        if(value === ''){
          callback('请输入长度为4-8位包含数字、字母、特殊字符的密码')
        } else {
          const reg = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\W_]).{4,8}$/
          if(reg.test(value)){
            callback()
          } else {
            callback('请输入长度为4-8位包含数字、字母、特殊字符的密码')
          } 
        }
      },
      validatePass2(rule, value, callback){
        if(value === ''){
          callback('请再次输入密码')
        } else if(value !== this.form.pass) {
          callback('两次输入密码不一致!')
        } else {
          callback()
        }
      },
      sendVerifyCode(){
        /** validateField 对部分表单字段进行校验的方法 */
        this.$refs.form.validateField('phone', errorMessage => {
          if(!errorMessage){
            // 发送接口请求后按钮进入倒计时状态
            /**
             * 时间开始倒数
             * 按钮进入禁用状态
             * 如果倒计时结束 按钮恢复可用状态 按钮文字变成重新发送 把倒计时时间重置
             * 倒计时的过程中 按钮文字显示为 多少s后重新发送
             */
            let timer = setInterval(() => {
              this.time-- // 时间进入倒计时
              this.btnText = `${this.time}s后重新发送`
              this.isLoading = true // 按钮显示加载中
              this.isDisabled = true // 按钮禁用
              console.log(this.time)
              if(this.time === 0){
                 this.btnText = '重新发送'
                 this.time = 10 // 重置时间
                 this.isLoading = false // 重置加载按钮
                 this.isDisabled = false // 重置按钮
                 clearInterval(timer)
              }
            }, 1000)
          }
        })
      }
    }
  }
</script>

<style scoped>
  a{
    text-decoration: none;
    color:#409EFF;
  }
</style>

 validateField方法对部分表单字段进行校验_菜鸟黑一枚-CSDN博客_validatefields校验单个

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于element-ui的表单校验,你可以通过以下步骤来实现: 1. 在表单中使用`<el-form>`标签包裹需要校验表单元素。 2. 为每个需要校验表单元素添加`prop`属性,该属性的值用于标识该表单元素。 3. 使用`rules`属性为每个表单元素定义校验规则,`rules`是一个数组,每个元素代表一个校验规则对象。 4. 在校验规则对象中,可以使用不同的校验方法,如`required`、`min`、`max`、`pattern`等。 5. 可以通过`message`属性为校验规则定义错误提示信息。 下面是一个简单的示例代码: ```html <template> <el-form :model="form" :rules="rules" ref="form"> <el-form-item label="用户名" prop="username"> <el-input v-model="form.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="form.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> </el-form-item> </el-form> </template> <script> export default { data() { return { form: { username: '', password: '' }, rules: { username: [ { required: true, message: '请输入用户名', trigger: 'blur' } ], password: [ { required: true, message: '请输入密码', trigger: 'blur' }, { min: 6, max: 20, message: '密码长度在 6 到 20 个字符', trigger: 'blur' } ] } }; }, methods: { submitForm() { this.$refs.form.validate((valid) => { if (valid) { // 表单校验通过,执行提交操作 console.log('表单校验通过'); } else { // 表单校验不通过,给出错误提示 console.log('表单校验不通过'); } }); } } }; </script> ``` 在上述示例中,`form`对象是表单数据的模型,`rules`对象定义了表单元素的校验规则。`submitForm`方法用于提交表单,其中通过`this.$refs.form.validate`方法来触发表单校验,并在回调函数中处理校验结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值