123 lines
3.4 KiB
Plaintext
123 lines
3.4 KiB
Plaintext
<template>
|
||
<view class="captcha-a">
|
||
<view id="captcha-element"></view>
|
||
</view>
|
||
</template>
|
||
|
||
<script lang="uts" setup>
|
||
// 阿里云验证码配置类型定义
|
||
interface AliyunCaptchaConfig {
|
||
captchaSceneId: string; // 场景ID
|
||
captchaPrefix: string; // 身份标
|
||
openCaptcha?: boolean; // 是否开启验证码
|
||
// 其他可能的配置项
|
||
}
|
||
|
||
// 阿里云验证码初始化选项
|
||
interface CaptchaOptions {
|
||
SceneId: string; // 场景ID
|
||
prefix: string; // 身份标
|
||
mode: 'popup' | 'embed'; // 验证码模式:弹出式或嵌入式
|
||
element: string; // 渲染验证码的元素
|
||
button: string; // 触发验证码弹窗的元素
|
||
captchaVerifyCallback: (param: any) => {
|
||
captchaResult: boolean;
|
||
bizResult: boolean;
|
||
};
|
||
onBizResultCallback: () => void;
|
||
getInstance: (instance: any) => void;
|
||
slideStyle?: {
|
||
width: number;
|
||
height: number;
|
||
};
|
||
language?: 'cn' | 'tw' | 'en'; // 验证码语言类型
|
||
}
|
||
|
||
// 全局类型声明
|
||
declare global {
|
||
interface Window {
|
||
initAliyunCaptcha: (options: CaptchaOptions) => void;
|
||
}
|
||
}
|
||
|
||
interface AliyunCaptchaProps {
|
||
config: AliyunCaptchaConfig;
|
||
elementId: string;
|
||
// doAction: (captchaVerifyParam: any) => void;
|
||
// onReady?: () => void; // 使用可选属性避免undefined调用
|
||
}
|
||
|
||
const props = defineProps<AliyunCaptchaProps>()
|
||
|
||
const emit = defineEmits(['doAction', 'onReady'])
|
||
// 验证码是否初始化完成
|
||
const captchaInited = ref<boolean>(false)
|
||
|
||
// 使用useCallback缓存回调函数,避免不必要的重新渲染
|
||
const captchaVerifyCallback = (captchaVerifyParam: any) => {
|
||
emit('doAction', captchaVerifyParam);
|
||
return {
|
||
captchaResult: true,
|
||
bizResult: true,
|
||
};
|
||
};
|
||
|
||
// 清理验证码相关DOM元素
|
||
const cleanupCaptchaElements = () => {
|
||
document.getElementById('aliyunCaptcha-mask')?.remove();
|
||
document.getElementById('aliyunCaptcha-window-popup')?.remove();
|
||
}
|
||
|
||
// 获取验证码实例
|
||
const getInstance = (instance: any) => {
|
||
if (instance) {
|
||
captchaInited.value = true;
|
||
}
|
||
}
|
||
|
||
watch(captchaInited, (newVal) => {
|
||
if (newVal) {
|
||
emit('onReady');
|
||
console.log('验证码初始化完成,onReady已调用');
|
||
}
|
||
})
|
||
|
||
// 初始化阿里云验证码
|
||
const initCaptcha = () => {
|
||
try {
|
||
// 初始化验证码
|
||
window.initAliyunCaptcha({
|
||
SceneId: props.config.captchaSceneId, // 场景ID
|
||
prefix: props.config.captchaPrefix, // 身份标
|
||
mode: 'popup', // 验证码模式:弹出式
|
||
element: '#captcha-element', // 渲染验证码的元素
|
||
button: `#${props.elementId}`, // 触发验证码弹窗的元素
|
||
captchaVerifyCallback, // 业务请求回调函数
|
||
onBizResultCallback: () => {}, // 业务请求结果回调函数
|
||
getInstance, // 绑定验证码实例函数
|
||
slideStyle: {
|
||
width: 320,
|
||
height: 40,
|
||
}, // 滑块验证码样式
|
||
language: 'cn', // 验证码语言类型
|
||
});
|
||
} catch (error) {
|
||
console.error('阿里云验证码初始化错误:', error);
|
||
}
|
||
};
|
||
|
||
watch(() => props.config, (newVal) => {
|
||
if (newVal && newVal.openCaptcha) {
|
||
initCaptcha();
|
||
}
|
||
}, { deep: true, immediate: true })
|
||
|
||
onUnmounted(() => {
|
||
// 组件卸载时清理DOM元素
|
||
cleanupCaptchaElements();
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
|
||
</style> |