【vue】vue前端实现随机验证码(数字、字母混合)功能

效果图:使用canvas组件对随机的数字字母添加插画背景、干扰线、干扰点

1、在components文件夹下新建securityCode.vue文件,代码:

js 复制代码
<template>
	<canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
</template>
<script>
	export default {
		name: "securityCode",
		props: {
			identifyCode: {
				type: String,
				default: "",
			},
			fontSizeMin: {
				type: Number,
				default: 22,
			},
			fontSizeMax: {
				type: Number,
				default: 40,
			},
			backgroundColorMin: {
				type: Number,
				default: 180,
			},
			backgroundColorMax: {
				type: Number,
				default: 240,
			},
			colorMin: {
				type: Number,
				default: 50,
			},
			colorMax: {
				type: Number,
				default: 160,
			},
			lineColorMin: {
				type: Number,
				default: 40,
			},
			lineColorMax: {
				type: Number,
				default: 180,
			},
			dotColorMin: {
				type: Number,
				default: 0,
			},
			dotColorMax: {
				type: Number,
				default: 255,
			},
			contentWidth: {
				type: Number,
				default: 120,
			},
			contentHeight: {
				type: Number,
				default: 40,
			},
		},
		methods: {
			// 生成一个随机数
			randomNum(min, max) {
				return Math.floor(Math.random() * (max - min) + min);
			},
			// 生成一个随机的颜色
			randomColor(min, max) {
				let r = this.randomNum(min, max);
				let g = this.randomNum(min, max);
				let b = this.randomNum(min, max);
				return "rgb(" + r + "," + g + "," + b + ")";
			},
			drawPic() {
				let canvas = document.getElementById("s-canvas");
				let ctx = canvas.getContext("2d");
				ctx.textBaseline = "bottom";
				// 绘制背景
				ctx.fillStyle = this.randomColor(
					this.backgroundColorMin,
					this.backgroundColorMax
				);
				ctx.fillRect(0, 0, this.contentWidth, this.contentHeight);
				// 绘制文字
				for (let i = 0; i < this.identifyCode.length; i++) {
					this.drawText(ctx, this.identifyCode[i], i);
				}
				this.drawLine(ctx);
				this.drawDot(ctx);
			},
			drawText(ctx, txt, i) {
				ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax);
				ctx.font =
					this.randomNum(this.fontSizeMin, this.fontSizeMax) + "px SimHei";
				let x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1));
				let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5);
				var deg = this.randomNum(-45, 45);
				// 修改坐标原点和旋转角度
				ctx.translate(x, y);
				ctx.rotate((deg * Math.PI) / 330);
				ctx.fillText(txt, 0, 0);
				// 恢复坐标原点和旋转角度
				ctx.rotate((-deg * Math.PI) / 330);
				ctx.translate(-x, -y);
			},
			drawLine(ctx) {
				// 绘制干扰线
				for (let i = 0; i < 3; i++) {
					ctx.strokeStyle = this.randomColor(
						this.lineColorMin,
						this.lineColorMax
					);
					ctx.beginPath();
					ctx.moveTo(
						this.randomNum(0, this.contentWidth),
						this.randomNum(0, this.contentHeight)
					);
					ctx.lineTo(
						this.randomNum(0, this.contentWidth),
						this.randomNum(0, this.contentHeight)
					);
					ctx.stroke();
				}
			},
			drawDot(ctx) {
				// 绘制干扰点
				for (let i = 0; i < 80; i++) {
					ctx.fillStyle = this.randomColor(0, 255);
					ctx.beginPath();
					ctx.arc(
						this.randomNum(0, this.contentWidth),
						this.randomNum(0, this.contentHeight),
						1,
						0,
						2 * Math.PI
					);
					ctx.fill();
				}
			},
		},
		watch: {
			identifyCode() {
				this.drawPic();
			},
		},
		mounted() {
			this.drawPic();
		},
	};
</script>

2、在登录页面引入并注册使用组件:

html 复制代码
<el-form-item prop="pass" label="验证码" class="row" label-width="150px">
	<div class="row space-between" style="width: 315px;">
		<el-input type="text" style="width: 190px;" v-model="inputCode" autocomplete="off"></el-input>
		<div @click="refreshCode()" style="line-height: 0;">
			<!--验证码组件-->
			<SecurityCode :identifyCode="identifyCode"></SecurityCode>
		</div>
	</div>
</el-form-item>
<el-form-item style="padding-left: 55px;">
	<el-button type="primary" @click="submitForm()" icon="el-icon-s-custom">
		<span style="font-size: 15px;letter-spacing: 10px;">登录</span>
	</el-button>
</el-form-item>
js 复制代码
<script>
	//导入组件
	import SecurityCode from "@/components/securityCode";
	export default {
		components: {//注册
			SecurityCode
		},
        data() {
            identifyCode: "",//随机组合字符串
			inputCode: "", //text框输入的验证码
        },
        mounted() {
			this.refreshCode();
		},
        methods: {
			//初始化验证码
			refreshCode() {
				this.inputCode = ''
				this.identifyCode = ""; //输入框置空
				this.makeCode(4); //验证码长度为4
			},
			//随机切换验证码
			makeCode(length) {
				let code = '';
				for (let i = 0; i < length; i++) {
					const r = Math.floor(Math.random() * 36);
					if (r < 10) {
						code += r;
					} else {
						code += String.fromCharCode(r - 10 + 65);
					}
				}
				this.identifyCode = code
				localStorage.setItem('code', code);
				console.log(this.identifyCode);
			},
            submitForm(formName) {
				const code = this.inputCode.toLowerCase();
				const originalCode = localStorage.getItem('code').toLowerCase();
				if (!code) {
					this.$message.error('请输入验证码!');
					return
				} else if (code !== originalCode) {
					this.$message.error('验证码输入错误!');
					this.refreshCode()
					return
				}
				// this.$api.Login({
				// 	userName: this.ruleForm.user,
				// 	password: this.ruleForm.pass,
				// 	systemCode: null,
				// }).then((data) => {
				// })
			},
        }
    }
</script>
相关推荐
Json_181790144801 小时前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
风尚云网1 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
木子02041 小时前
前端VUE项目启动方式
前端·javascript·vue.js
GISer_Jing1 小时前
React核心功能详解(一)
前端·react.js·前端框架
捂月1 小时前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
深度混淆1 小时前
实用功能,觊觎(Edge)浏览器的内置截(长)图功能
前端·edge
Smartdaili China1 小时前
如何在 Microsoft Edge 中设置代理: 快速而简单的方法
前端·爬虫·安全·microsoft·edge·社交·动态住宅代理
秦老师Q1 小时前
「Chromeg谷歌浏览器/Edge浏览器」篡改猴Tempermongkey插件的安装与使用
前端·chrome·edge
滴水可藏海1 小时前
Chrome离线安装包下载
前端·chrome
m51272 小时前
LinuxC语言
java·服务器·前端