先看效果
创建 GraphicCaptchas.vue
文件
html代码
<template> <div class="captcha-image-wrapper" @click="refreshCaptcha"> <img :src="captchaImage" class="captcha-image" alt="验证码"/> </div> </template>
JavaScript代码
<script setup> import { ref, onMounted, defineEmits } from 'vue' // 生成图片验证码地址 const captchaImage = ref('') // 生成随机验证码 const generateCaptcha = () => { const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' let captcha_value = '' for (let i = 0; i < 4; i++) { captcha_value += chars.charAt(Math.floor(Math.random() * chars.length)) } // 触发事件将验证码传递给父组件 emit('update:captcha', captcha_value) return captcha_value } // 创建验证码图片 const createCaptchaImage = (text) => { const canvas = document.createElement('canvas') canvas.width = 140 canvas.height = 40 const ctx = canvas.getContext('2d') ctx.fillStyle = '#f0f4f8' ctx.fillRect(0, 0, canvas.width, canvas.height) // 添加干扰线 for (let i = 0; i < 5; i++) { ctx.strokeStyle = `rgb(${Math.floor(Math.random() * 150)}, ${Math.floor(Math.random() * 150)}, ${Math.floor(Math.random() * 150)})` ctx.beginPath() ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height) ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height) ctx.stroke() } // 添加噪点 for (let i = 0; i < 100; i++) { ctx.fillStyle = `rgb(${Math.floor(Math.random() * 150)}, ${Math.floor(Math.random() * 150)}, ${Math.floor(Math.random() * 150)})` ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 1, 1) } ctx.font = '24px Arial' ctx.fillStyle = '#4361ee' ctx.textAlign = 'center' ctx.textBaseline = 'middle' for (let i = 0; i < text.length; i++) { ctx.save() ctx.translate(25 + i * 30, 20) ctx.rotate((Math.random() - 0.5) * 0.4) ctx.fillText(text[i], 0, 0) ctx.restore() } return canvas.toDataURL() } // 刷新验证码 const refreshCaptcha = () => { const captchaText = generateCaptcha() captchaImage.value = createCaptchaImage(captchaText) } // 初始化验证码 onMounted(() => { refreshCaptcha() }) //暴露验证码的值 const emit = defineEmits(['update:captcha']) // 暴露方法给父组件 defineExpose({ refreshCaptcha }) </script>
css代码
.captcha-image-wrapper { position: relative; width: 120px; height: 40px; border-radius: 8px; overflow: hidden; cursor: pointer; border: 1px solid #e2e8f0; background-color: #f0f4f8; } .captcha-image { width: 100%; height: 100%; object-fit: cover; } .captcha-image-wrapper:hover .captcha-refresh { background-color: #4361ee; } .captcha-image-wrapper:hover .captcha-refresh svg path { fill: white; }
如何使用
<Graphic-Captchas ref="captchaRef" v-model:captcha="currentCaptcha"/> import GraphicCaptchas from "@/components/GraphicCaptchas/GraphicCaptchas.vue"; //验证码 const captchaRef = ref(null) const currentCaptcha = ref('') captchaRef.value.refreshCaptcha() //调用子组件刷新验证码的方法