Vue简单自定义Canvas验证码组件。

在您的Vue项目中,是否曾遇到过需要增加验证码来增强账户安全性的情况?这个Vue通用Canvas验证码组件!采用Canvas,实现了高度自定义和灵活的验证码生成方式,让您的网站或应用轻松应对各类验证码需求。

在线演示地址: 验证码演示

一,创建一个Captcha验证码组件。

<template>
     <canvas id="captchaCanvas" @click="generateCaptcha" :style="{width,height}"></canvas>
</template>

<script setup>
import {watch, onMounted, toRefs} from "vue";
const emit=defineEmits(['getValue'])
const props = defineProps({
  // 宽度
  width: {
    type: String,
    default: '100%'
  },
  // 高度
  height: {
    type: String,
    default: '100%'
  },
  //验证码数量
  number: {
    type: Number,
    default: 4,
  }, //验证码数量
  night: {
    type: Boolean,
    default: false,
  },
});
watch(()=>props.night,()=>{
  generateCaptcha()
})
const  generateCaptcha=()=> {
  const canvas = document.getElementById('captchaCanvas');
  const ctx = canvas.getContext('2d');
  // 清除旧内容
  canvas.width = canvas.width;
  // 字符集
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let captchaText = '';
  // 设置背景颜色和一些基本样式
  ctx.fillStyle = props.night?'#2d2c2c':'#f9f9f9';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  // 绘制噪点
  for (let i = 0; i < 200; i++) {
    ctx.fillStyle = getRandomColor(0, 300);
    ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 1, 1);
  }
  // 绘制干扰线
  for (let i = 0; i < 9; i++) {
    ctx.strokeStyle = getRandomColor(150, 255);
    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 < props.number; i++) { 
    const randomIndex = Math.floor(Math.random() * chars.length);
    const char = chars[randomIndex];
    captchaText += char;
    drawChar(char, 1 + i * canvas.width/props.number, (canvas.height/2)+20, 70, getRandomColor(10, 50));
  }
  //返回给父组件
  emit('getValue',captchaText)
}
const drawChar=(char, x, y, fontSize, fillStyle)=> {
  const ctx = document.getElementById('captchaCanvas').getContext('2d');
  ctx.font = fontSize + 'px Arial';
  ctx.fillStyle = fillStyle;
  ctx.fillText(char, x, y);
}

const  getRandomColor=(min, max)=> {
  var r = Math.floor(Math.random() * 256); // 0-255
  var g = Math.floor(Math.random() * 256);
  var b = Math.floor(Math.random() * 256);
  return `rgb(${r},${g},${b})`;
}
//暴露给父组件调用
defineExpose({generateCaptcha})
onMounted(()=>{
  generateCaptcha();
})
</script>

<style scoped>
#captchaCanvas {
  margin-bottom: 10px;
  display: block;
  user-select: none;
}
</style>

二,页面中引入该组件。

<template>
  <div style="width: 200px;height: 80px">
    <Captcha ref="captchaRef" @getValue="getValue" ></Captcha>
  </div>
</template>

<script setup>
import Captcha from '../components/Captcha.vue';
const getValue=(val)=>{
  console.log('验证码值=',val)
}

</script>

<style >
body{
  display: flex;
  justify-content: center;
}
</style>

三,效果图。

验证码效果图

四,其他

属性名称 说明
width 宽度(String),默认100%跟随父级宽度
height 高度(String),默认100%跟随父级高度
number 验证码个数(Number),默认4
night 黑夜模式(Boolean),默认false
方法名称 说明
getValue (string)=>{},返回验证码值
ZhangApple
更多

发布时间:2024年06月07日

本文作者:ZhangApple。转载请注明并附上本文链接

评论一下

评论列表