本页导航
article
验证码封装
AI摘要
Vue3 EasyCaptcha 验证码组件封装,实现验证码显示和校验功能
<template>
<el-form-item class="login-container" prop="verifyCode" label="验证码">
<el-input
v-model="captchaData.verifyCode"
auto-complete="off"
placeholder="请输入右侧的计算结果"
clearable
class="input"
size="large"
@change="verifyCaptcha"
@input="setVerifyCode"
>
<template #prefix>
<svg-icon icon-class="verify_code"/>
</template>
</el-input>
<div class="captcha">
<img :src="captchaBase64" @click="getCaptcha"/>
</div>
</el-form-item>
</template>
<script lang="ts" setup>
import SvgIcon from "@/components/SvgIcon/index.vue";
import { getCaptchaApi } from "@/api/auth";
import { CaptchaCheck, CaptchaControllerService } from "@/generated";
const props = defineProps({
verifyCode: {
type: String,
required: true
},
rules: {
type: Object,
required: true
}
});
const emit = defineEmits(['update:verifyCode']);
const setVerifyCode = (value: string) => {
emit('update:verifyCode', value); // 发送自定义事件更新父组件的 verifyCode 值
};
watch(() => props.verifyCode, (newValue) => {
captchaData.value.verifyCode= newValue; // 当从父组件传来的 verifyCode 值变化时,更新本地的 verifyCode 值
});
/**
* 验证码图片Base64字符串
*/
const captchaBase64 = ref();
const captchaData = ref<CaptchaCheck>({
verifyCode: props.verifyCode,
verifyCodeKey: "",
});
let selfRules = ref({})
const veriflCode = [{
validator: verifyCaptcha,
trigger: 'blur'
}]
/**
* 获取验证码
*/
function getCaptcha() {
getCaptchaApi().then(({ data }) => {
const { verifyCodeBase64, verifyCodeKey } = data;
captchaData.value.verifyCodeKey = verifyCodeKey;
captchaBase64.value = verifyCodeBase64;
});
}
/**
* 校验
*/
async function verifyCaptcha (rule: any, value: any, callback: any) {
if (value){
return new Promise((resolve, reject) => {
CaptchaControllerService.checkCaptcha(captchaData.value)
.then((res) => {
const code = res.data
if (code !== value){
callback(new Error('验证码错误!'))
} else if(!code){
callback(new Error('验证码超时!'))
}else {
callback()
}
})
.catch((error: any) => {
reject(error);
getCaptcha();
});
})
} else {
callback(new Error('验证码不能为空!'))
}
}
onBeforeMount(() => {
selfRules.value = props.rules
selfRules.value.verifyCode = veriflCode
})
onMounted(() => {
getCaptcha();
});
</script>
<style lang="scss" scoped>
:deep(.el-form-item__content){
display: flex;
flex-grow: 1;
flex-wrap: nowrap;
align-items: center;
justify-content: left;
}
:deep(.el-form-item__label){
height: 48px;
line-height: 48px;
}
.login-container {
width: 500px;
//padding: 20px 35px 0;
display: flex;
white-space: nowrap;
.input {
background: transparent;
height: 48px;
flex-grow: 1;
// 子组件 scoped 无效,使用 :deep
//:deep(.el-input__wrapper) {
// padding: 0;
// background: transparent;
// box-shadow: none;
//
// .el-input__inner {
// color: #fff;
// background: transparent;
// border: 0;
// border-radius: 0;
// caret-color: #fff;
//
// &:-webkit-autofill {
// box-shadow: 0 0 0 1000px transparent inset !important;
// -webkit-text-fill-color: #fff !important;
// }
//
// // 设置输入框自动填充的延迟属性
// &:-webkit-autofill,
// &:-webkit-autofill:hover,
// &:-webkit-autofill:focus,
// &:-webkit-autofill:active {
// transition: color 99999s ease-out, background-color 99999s ease-out;
// transition-delay: 99999s;
// }
// }
//}
}
.captcha {
margin-left: 1px;
img {
width: 120px;
height: 48px;
cursor: pointer;
display: flex;
align-items: center;
}
}
}
</style>
最后更新于 2026-02-11 18:51