first commit
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onBeforeUnmount, ref } from 'vue';
|
||||
|
||||
const props = defineProps<{ sitekey: string }>();
|
||||
const emit = defineEmits<{ verified: [token: string] }>();
|
||||
|
||||
const container = ref<HTMLDivElement | null>(null);
|
||||
const widgetId = ref<number | null>(null);
|
||||
|
||||
const SCRIPT_ID = 'recaptcha-api';
|
||||
const CALLBACK = '__vanguardRecaptchaLoaded';
|
||||
|
||||
interface Grecaptcha {
|
||||
render(el: HTMLElement, options: Record<string, unknown>): number;
|
||||
reset(id?: number): void;
|
||||
}
|
||||
|
||||
function grecaptcha(): Grecaptcha | undefined {
|
||||
return (window as unknown as { grecaptcha?: Grecaptcha }).grecaptcha;
|
||||
}
|
||||
|
||||
function renderWidget() {
|
||||
const api = grecaptcha();
|
||||
|
||||
if (!api || !container.value || widgetId.value !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
widgetId.value = api.render(container.value, {
|
||||
sitekey: props.sitekey,
|
||||
callback: (token: string) => emit('verified', token),
|
||||
'expired-callback': () => emit('verified', ''),
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (grecaptcha()) {
|
||||
renderWidget();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
(window as unknown as Record<string, unknown>)[CALLBACK] = renderWidget;
|
||||
|
||||
if (!document.getElementById(SCRIPT_ID)) {
|
||||
const script = document.createElement('script');
|
||||
script.id = SCRIPT_ID;
|
||||
script.src = `https://www.google.com/recaptcha/api.js?onload=${CALLBACK}&render=explicit`;
|
||||
script.async = true;
|
||||
script.defer = true;
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (widgetId.value !== null) {
|
||||
grecaptcha()?.reset(widgetId.value);
|
||||
}
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
reset: () => {
|
||||
if (widgetId.value !== null) {
|
||||
grecaptcha()?.reset(widgetId.value);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="container" />
|
||||
</template>
|
||||
Reference in New Issue
Block a user