GoogleRecaptcha.vue 这是封装的组件
<template>
<!-- reCAPTCHA 容器 -->
<div ref="recaptcha" class="g-recaptcha"></div>
</template>
<script>
export default {
data() {
return {
reCaptchaResponse: null, // reCAPTCHA 实例
};
},
mounted() {
window.addEventListener("resize", this.ScaleReCaptcha);
this.loadReCaptchaScript()
.then(() => {
// 确保 grecaptcha 已经加载
if (window.grecaptcha) {
// 将 renderReCaptcha 暴露为全局函数
window.renderReCaptcha = this.renderReCaptcha;
this.renderReCaptcha(); // 调用渲染函数
} else {
console.error("grecaptcha is not available");
}
})
.catch((error) => {
console.error("Failed to load reCAPTCHA script:", error);
});
},
methods: {
// 动态加载 reCAPTCHA 脚本
loadReCaptchaScript() {
return new Promise((resolve, reject) => {
if (window.grecaptcha) {
resolve(); // 如果 grecaptcha 已加载,直接返回
return;
}
const script = document.createElement("script");
script.src =
"https://www.recaptcha.net/recaptcha/api.js?onload=renderReCaptcha&render=explicit&hl=en";
script.async = true;
script.defer = true;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
},
// 使用 grecaptcha.render 渲染 reCAPTCHA
renderReCaptcha() {
this.recaptchaInstance = window.grecaptcha.render(this.$refs.recaptcha, {
sitekey: "你申请的前端公钥", //公钥
theme: "light", //主题颜色,有light与dark两个值可选
size: "normal", //尺寸规则,有normal与compact两个值可选
callback: this.onCaptchaVerified, //验证成功回调
"expired-callback": this.onReCaptchaExpired, //验证过期回调
});
this.ScaleReCaptcha();
},
// reCAPTCHA 验证通过后的回调
onCaptchaVerified(response) {
console.log("reCAPTCHA response:", response); // 可以在这里处理响应
this.reCaptchaResponse = response;
response.length > 0
? this.$emit("getValidateCode", true)
: this.$emit("getValidateCode", false);
},
onReCaptchaExpired() {
console.log("reCAPTCHA 验证过期");
this.reCaptchaResponse = null;
this.$emit("getValidateCode", false);
},
ScaleReCaptcha() {
// reCAPTCHA 自适应尺寸缩放
let _recaptcha = document.getElementsByClassName("g-recaptcha");
if (_recaptcha.length > 0) {
let parentWidth = _recaptcha[0].parentNode.clientWidth;
let childWidth = _recaptcha[0].firstChild.clientWidth;
let scale = parentWidth / childWidth;
_recaptcha[0].style.transform = "scale(" + scale + ")";
_recaptcha[0].style.transformOrigin = "0 0";
}
},
resetReCaptcha() {
if (this.recaptchaInstance) {
window.grecaptcha.reset();
}
},
},
};
</script>
<style scoped lang="scss">
.g-recaptcha {
height: 90px;
transform: scale(0.78);
-webkit-transform: scale(0.78);
transform-origin: 0 0;
-webkit-transform-origin: 0 0;
}
.rc-anchor-normal.rc-anchor-error .rc-anchor-error-msg-container {
width: 260px !important;
}
</style>
https://www.recaptcha.net/recaptcha/api.js?οnlοad=renderReCaptcha&render=explicit&hl=en
hl=en是语言,自定义
https://developers.google.com/recaptcha/docs/display?hl=zh-cn
父级
<GoogleRecaptcha
ref="GoogleRecaptcha"
@getValidateCode="getValidateCode"
></GoogleRecaptcha>