vue封装验证码组件

先看效果

yzm.png
Snipaste_2025-06-10_13-33-12.png

创建 GraphicCaptchas.vue 文件

  1. html代码

    <template>
      <div class="captcha-image-wrapper" @click="refreshCaptcha">
     <img :src="captchaImage" class="captcha-image" alt="验证码"/>
      </div>
    </template>
  2. 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>
  3. 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() //调用子组件刷新验证码的方法
无标签
评论区
头像
文章目录