代码定义了表单验证规则 rules,用于校验 phone(手机号)和 smsCode(验证码)字段。但目前的规则只检查了必填项,没有对手机号的格式进行校验。

如何改进?

1. 添加手机号格式校验

可以使用 validator 自定义校验规则,确保手机号符合 1[3-9]\d{9} 的格式(11位数字,1开头,第二位是3-9)。

const rules: FormRules = {
  phone: [
    {
      required: true,
      message: '请输入手机号',
      trigger: 'blur',
    },
    {
      pattern: /^1[3-9]\d{9}$/,
      message: '请输入正确的手机号',
      trigger: 'blur',
    },
  ],
  smsCode: [
    { 
      required: true, 
      message: '请输入验证码', 
      trigger: 'blur' 
    },
  ],
};

2. 或者使用 validator 自定义校验(更灵活)

const validatePhone = (rule: any, value: string, callback: any) => {
  if (!value) {
    callback(new Error('请输入手机号'));
  } else if (!/^1[3-9]\d{9}$/.test(value)) {
    callback(new Error('请输入正确的手机号'));
  } else {
    callback();
  }
};

const rules: FormRules = {
  phone: [
    { 
      validator: validatePhone, 
      trigger: 'blur' 
    },
  ],
  smsCode: [
    { 
      required: true, 
      message: '请输入验证码', 
      trigger: 'blur' 
    },
  ],
};

这样,phone 字段会在 blur 时触发校验,确保输入的是有效的手机号。


完整示例(结合你的获取验证码逻辑)

<script setup lang="ts">
import { ref } from 'vue';
import { ElMessage, type FormRules } from 'element-plus';

const param = ref({
  phone: '',
  smsCode: '',
});

const countdown = ref(0);
const timer = ref<NodeJS.Timeout | null>(null);
const formRef = ref();

// 手机号校验规则
const validatePhone = (rule: any, value: string, callback: any) => {
  if (!value) {
    callback(new Error('请输入手机号'));
  } else if (!/^1[3-9]\d{9}$/.test(value)) {
    callback(new Error('请输入正确的手机号'));
  } else {
    callback();
  }
};

const rules: FormRules = {
  phone: [
    { 
      validator: validatePhone, 
      trigger: 'blur' 
    },
  ],
  smsCode: [
    { 
      required: true, 
      message: '请输入验证码', 
      trigger: 'blur' 
    },
  ],
};

// 获取验证码(带校验)
const handleGetVerificationCode = async () => {
  try {
    // 先校验手机号
    await formRef.value.validateField('phone');
    
    // 校验通过后执行获取验证码逻辑
    startCountdown();
    ElMessage.success('验证码已发送');
  } catch (error) {
    console.log('手机号校验失败:', error);
  }
};

// 倒计时逻辑
const startCountdown = () => {
  if (countdown.value > 0) return;
  
  countdown.value = 60;
  timer.value = setInterval(() => {
    countdown.value--;
    if (countdown.value <= 0) {
      clearInterval(timer.value!);
      timer.value = null;
    }
  }, 1000);
};

// 组件卸载时清除定时器
onBeforeUnmount(() => {
  if (timer.value) {
    clearInterval(timer.value);
  }
});
</script>

<template>
  <el-form :model="param" :rules="rules" ref="formRef">
    <el-form-item prop="phone">
      <el-input v-model="param.phone" placeholder="请输入手机号">
        <template #prepend>
          <el-icon><Iphone /></el-icon>
        </template>
      </el-input>
    </el-form-item>

    <el-form-item prop="smsCode">
      <el-input v-model="param.smsCode" placeholder="请输入验证码">
        <template #append>
          <el-button 
            @click="handleGetVerificationCode"
            :disabled="countdown > 0"
          >
            {{ countdown > 0 ? `${countdown}秒后重新获取` : '获取验证码' }}
          </el-button>
        </template>
      </el-input>
    </el-form-item>
  </el-form>
</template>

关键点

  1. rules定义
  • phone 使用 validator 或 pattern 校验手机号格式。
  • smsCode 只需检查必填。
  1. 获取验证码流程
  • 先校验手机号 → 通过后开始倒计时 → 发送验证码。
  1. 倒计时逻辑
  • 60秒倒计时,期间按钮禁用,结束后恢复。

这样你的表单既能校验手机号格式,又能安全地获取验证码!

获取验证码后 改为60秒倒计时 60秒之后 改为获取验证码_ico