实现思路:

一、表单验证

1、手机号验证,满足11位,且第3位为 3578 这一个数字

// 表单格式验证
// 手机号验证
const validatePhone = (rule: any, value: any, callback: any) => {
  let str=new RegExp("^1[3578]\\d{9}$");
  if(!str.test(value)){
    callback(new Error('手机号错误!'))
  }else{
    callback()
  }
}

const rules = reactive({
  phone: [{ validator: validatePhone, trigger: 'blur' }]
})

2、新密码以及确认密码验证,请设置6-20位字母,数字的两种组合

// 新密码验证
const validatePass = (rule: any, value: any, callback: any) => {
    if (value === '') {
        callback(new Error('密码不能为空!'))
    } else {
        if (ruleForm.checkPass !== '') {
            if (!ruleFormRef.value) return
            ruleFormRef.value.validateField('checkPass', () => null)
        }
    }
    var str = RegExp("^[0-9a-zA-Z]*$")
    if(!str.test(value)||value.length<6||value.length>20){
        callback(new Error('当前密码格式不正确!'))
    }else{
        callback()
    }
}
// 确认密码验证
const validatePass2 = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('密码不能为空!'));
  } else if (value !== ruleForm.newPwd) {
    callback(new Error('两次输入密码不一致!'));
  } else {
    callback()
  }
}
const rules = reactive({
  newPwd: [{ validator: validatePass, trigger: 'blur' }],
  checkPass: [{ validator: validatePass2, trigger: 'blur' }],
})

二、输入手机号,点击获取验证码

发送请求给后台,后台通过程序发送短信,获取验证码,然后填写验证码

// 获取验证码
let timer:any = null
let VerCode= ()=>{
    if (!timer) {
        if(ruleForm.phone!==''){
            GetVerCode()
            timer = setTimeout(() => {
                clearTimeout(timer)
                timer = null
            }, 60000)
        }else{
            ElMessage('请输入手机号再试!')
        }
    }
}
// 发送验证码接口
let GetVerCode= async()=>{
    let res:TResponse<string>=await getVerCode({Mobile: ruleForm.phone})
    let {Code,Data,Message}= res
    if(Code===200){
        ruleForm.verCode=Data
        Time()
    }else{
        ElMessage(Message)
    }
}
// 设置倒计时60s
let Time=()=>{
    var codeBtn = document.getElementsByClassName('getYzm')[0]
    if (ruleForm.wait===0) {
        ruleForm.disabledValue=false
        codeBtn.innerHTML = "获取验证码"
        ruleForm.wait = 60
    }else{
        ruleForm.disabledValue=true
        codeBtn.innerHTML = ruleForm.wait + "秒后重试"
        ruleForm.wait--
        setTimeout(function(){
            Time()
        },1000)
    }
}

三、信息输入完成后,点击完成

1、md5加密:

A、安装 js-md5

cnpm install js-md5

B、main.js 引入

import md5 from 'js-md5'
const app = createApp(App)
app.config.globalProperties.$md5 = md5

C、局部引入

<script lang="ts" setup>
import md5 from "js-md5";
</script>

D、页面调用

// 全局引入调用方法
<script lang="ts" setup>
import { getCurrentInstance } from 'vue'

const { appContext } = getCurrentInstance()
let md5=appContext.config.globalProperties.$md5
md5('加密内容')
</script>

// 局部引入调用方法
<script lang="ts" setup>
md5('加密内容')
</script>

2、点击 “完成并登录” 按钮,空值校验

<el-form ref="ruleFormRef" :model="ruleForm" status-icon :rules="rules" class="demo-ruleForm">
    <el-form-item>
        <el-button class="loginBtn" @click="ResetPwd(ruleFormRef)">完成并登录</el-button>
    </el-form-item>
</el-form>
// 重置密码
const ResetPwd = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate((valid:any) => {
    if (valid) { // 提交成功
        GetResetPwd()
    } else {
      return false
    }
  })
}
// 提交接口
let GetResetPwd= async()=>{
    let res:TResponse<boolean>=await getResetPwd({Mobile: ruleForm.phone,SMSCode: ruleForm.verificationCode,Password: md5(ruleForm.checkPass).toUpperCase()})
    let {Code,Data,Message}= res
    if(Code===200){
        isShowDialog.value = false
        ElMessage('重置密码成功!')
    }else{
        ElMessage(Message)
    }
}

四、完整代码如下

<template>
    <div class="resetPassword">
        <el-dialog v-model="isShowDialog" :show-close="true" :close-on-press-escape="false" :close-on-click-modal="false">
            <div class="title">重置密码</div>
            <el-form ref="ruleFormRef" :model="ruleForm" status-icon :rules="rules" class="demo-ruleForm">
                <el-form-item label="" prop="phone">
                    <el-input v-model="ruleForm.phone" placeholder="请输入手机号码"></el-input>
                </el-form-item>
                <div class="row row2">
                    <el-input v-model="ruleForm.verificationCode" placeholder="请输入验证码"></el-input>
                    <div class="getYzm" @click="VerCode()">获取验证码</div>
                </div>
                <el-form-item label="" prop="newPwd">
                    <el-input type="password" v-model="ruleForm.newPwd" placeholder="请输入6-20位新密码" autocomplete="off"></el-input>
                    <div class="tips">请设置6-20位字母,数字的两种组合
                        <!-- ,不能与旧密码相同 -->
                    </div>
                </el-form-item>
                <el-form-item label="" prop="checkPass">
                    <el-input type="password" v-model="ruleForm.checkPass" placeholder="请再次输入密码" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button class="loginBtn" @click="ResetPwd(ruleFormRef)">完成并登录</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>

<script lang="ts" setup>
import { defineEmits, ref, reactive, watch, getCurrentInstance } from 'vue'
// 引入泛型的类型验证
import { TResponse } from "@/module/common"
// 调API
import { getResetPwd, getVerCode } from "@/api/login";
// elmentui组件
import { ElMessage } from 'element-plus'
import type { FormInstance } from 'element-plus'
import md5 from "js-md5";

const props = defineProps({
    isShow: {
        type: Boolean,
        default: false,
    },
})
let isShowDialog = ref(props.isShow)
watch(() => props.isShow, (newVal) => {
    isShowDialog.value = newVal
});

const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive({
    phone: '',// 电话
    verificationCode: '',// 验证码
    newPwd: '',//新密码
    checkPass: '',//确认新密码
    wait: 60 // 倒计时
})

// 表单格式验证
// 手机号验证
const validatePhone = (rule: any, value: any, callback: any) => {
  let str=new RegExp("^1[3578]\\d{9}$");
  if(!str.test(value)){
    callback(new Error('手机号错误!'))
  }else{
    callback()
  }
}
// 新密码验证
const validatePass = (rule: any, value: any, callback: any) => {
    if (value === '') {
        callback(new Error('密码不能为空!'))
    } else {
        if (ruleForm.checkPass !== '') {
            if (!ruleFormRef.value) return
            ruleFormRef.value.validateField('checkPass', () => null)
        }
    }
    var str = RegExp("^[0-9a-zA-Z]*$")
    if(!str.test(value)||value.length<6||value.length>20){
        callback(new Error('当前密码格式不正确!'))
    }else{
        callback()
    }
}
// 确认密码验证
const validatePass2 = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('密码不能为空!'));
  } else if (value !== ruleForm.newPwd) {
    callback(new Error('两次输入密码不一致!'));
  } else {
    callback()
  }
}
const rules = reactive({
  phone: [{ validator: validatePhone, trigger: 'blur' }],
  newPwd: [{ validator: validatePass, trigger: 'blur' }],
  checkPass: [{ validator: validatePass2, trigger: 'blur' }],
})

// 获取发送验证码
let timer:any = null
let VerCode= ()=>{
    if (!timer) {
        if(ruleForm.phone!==''){
            GetVerCode()
            timer = setTimeout(() => {
                clearTimeout(timer)
                timer = null
            }, 60000)
        }else{
            ElMessage('请输入手机号再试!')
        }
    }
}
let GetVerCode= async()=>{
    let res:TResponse<string>=await getVerCode({Mobile: ruleForm.phone})
    let {Code,Data,Message}= res
    if(Code===200){
        Time()
    }else if(Message==='用户不存在'){
        ElMessage('用户不存在')
    }
}
// 设置倒计时60s
let Time=()=>{
    var codeBtn = document.getElementsByClassName('getYzm')[0]
    if (ruleForm.wait===0) {
        codeBtn.innerHTML = "获取验证码"
        ruleForm.wait = 60
    }else{
        codeBtn.innerHTML = ruleForm.wait + "秒后重试"
        ruleForm.wait--
        setTimeout(function(){
            Time()
        },1000)
    }
}

// 重置密码
const ResetPwd = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate((valid:any) => {
    if (valid) { // 提交成功
        GetResetPwd()
    } else {
      return false
    }
  })
}
// 提交接口
let GetResetPwd= async()=>{
    let res:TResponse<boolean>=await getResetPwd({Mobile: ruleForm.phone,SMSCode: ruleForm.verificationCode,Password: md5(ruleForm.checkPass).toUpperCase()})
    let {Code,Data,Message}= res
    if(Code===200){
        isShowDialog.value = false
        ElMessage('重置密码成功!')
    }else{
        ElMessage(Message)
    }
}

</script>
<style lang="scss" scoped >
.resetPassword {
    .title {
        text-align: center;
        margin-bottom: 57px;
        font-weight: 600;
        font-size: 32px;
        line-height: 48px;
        letter-spacing: 0.065em;
        color: #434444;
    }

    /deep/ .el-dialog {
        padding: 34px 52px 0px 52px;
        margin-top: 190px !important;
        position: relative;
        width: 550px !important;
        height: 690px !important;
        background: #FFFFFF;
        border-radius: 20px;

        .el-dialog__body {
            padding: 0;
        }

        .row {
            margin-bottom: 30px;
        }

        .el-input__inner {
            width: 100% !important;
            height: 64px !important;
            border-radius: 10px;
            line-height: 64px;
            font-size: 20px;
            letter-spacing: 0.065em;
            color: #828282;
        }

        .row2 {
            display: flex;
            text-align: left;

            .el-input {
                width: 332px !important;
            }

            .el-input__inner {
                width: 332px !important;
            }

            .getYzm {
                width: calc(100% - 344px);
                height: 100%;
                border: 1px solid #3B86FF;
                border-radius: 10px;
                line-height: 64px;
                font-size: 16px;
                letter-spacing: 0.065em;
                color: #3B86FF;
                text-align: center;
                margin-left: 12px;
            }
        }

        .tips {
            font-size: 16px;
            line-height: 22px;
            letter-spacing: 0.065em;
            color: #3B86FF;
        }

        .loginBtn {
            width: 100%;
            height: 64px;
            text-align: center;
            background: #3B86FF;
            border-radius: 10px;
            font-size: 22px;
            color: #FBFBFB;
            cursor: pointer;
            border: 0;
        }
    }
}
</style>

其中文件 @/module/common.ts 

//接口返回的公共类型
export type TResponse<T> = {
    Code: number
    Data: T
    Message: string
}

文件 @/api/login.ts

 @/module/login, 根据后台返的接口来

        希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~

Logo

前往低代码交流专区

更多推荐