【vue】canvas验证码组件--数字/数字加字母
基于canvas的数字/数字+字符验证码 SIdentify.vue 组件
<!-- 基于canvas的数字/数字+字符验证码 --> <!-- 调用格式 <s-identify @func="getMsgFormSon" :isRefreshCode="isRefreshCode" :identifyCodes="identifyCodes" //可选传,选传写法有要求 ></s-identify> --> <template> <div class="s-canvas"> <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas> </div> </template> <script> export default { name: "SIdentify", props: { isRefreshCode: { type: Boolean, default: false }, identifyCodes: { type: Array }, identifyLen: { type: Number, default: 4 }, fontSizeMin: { type: Number, default: 16 }, 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: 112 }, contentHeight: { type: Number, default: 32 } }, data() { return { nums: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" ], identifyText: "" }; }, 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 + ")"; }, // 绘制干扰线 drawLine(ctx) { for (let i = 0; i < 6; 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 < 50; i++) { ctx.fillStyle = this.randomColor(0, 255); ctx.beginPath(); ctx.arc( this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, * Math.PI ); ctx.fill(); } }, // 生成l长度的验证码 makeCode(o, l) { let identifyCodes = o; this.identifyText = ""; for (let i = 0; i < l; i++) { this.identifyText += identifyCodes[this.randomNum(0, identifyCodes.length)]; } }, // 验证码文本 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.identifyText.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 / 180); ctx.fillText(txt, 0, 0); // 恢复坐标原点和旋转角度 ctx.rotate(-deg * Math.PI / 180); ctx.translate(-x, -y); }, // 验证码图形 drawPic() { let identifyCodesArray = this.identifyCodes ? this.identifyCodes : this.nums; this.makeCode(identifyCodesArray, this.identifyLen); let identifyCode = ""; 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); console.log(this.identifyText, "huizhi"); // 绘制文字 for (let i = 0; i < this.identifyLen; i++) { this.drawText(ctx, this.identifyText[i], i); identifyCode += this.identifyText[i]; } // for (let i = 0; i < this.identifyArray.length; i++) { // this.drawText(ctx, this.identifyArray[i], i); // } this.drawLine(ctx); this.drawDot(ctx); console.log(identifyCode, "要传的值"); // 向父组件传值 this.$emit("func", identifyCode); } }, watch: { if (this.isRefreshCode) { this.drawPic(); } }, mounted() { this.drawPic(); } }; </script> <style lang="scss" scoped> .s-canvas { height: 32px; canvas { margin-top: 1px; margin-left: 8px; } } </style>
父组件调用
①默认 数字+字母验证码 形式
<template> <div> <el-input v-model="verificationCode" placeholder="验证码" /> <div class="identify-code" @click="refreshCode"> <!--验证码组件--> <s-identify @func="getSidentifyCode" :isRefreshCode="isRefreshCode"></s-identify> </div> </div> </template> <script> import Vue from "vue"; import SIdentify from "./common/SIdentify"; export default { components: { SIdentify }, data() { return { verificationCode: "", identifyCode: "", isRefreshCode: false, }; }, created() { // this.refreshCode(); }, mounted() {}, watch: {}, methods: { refreshCode() { this.identifyCode = ""; this.isRefreshCode = true; //更改状态--SIdentify组件中监听该状态 }, getSidentifyCode(data) { this.identifyCode = data; this.isRefreshCode = false; console.log(this.identifyCode, "接收到的code"); } } }; </script> <style lang="scss" scoped> .identify-code { display: inline-block; } } </style>
②通过传 纯数字 为数字验证码
<template> <div> <el-input v-model="verificationCode" placeholder="验证码" /> <div class="identify-code" @click="refreshCode"> <!--验证码组件--> <s-identify @func="getSidentifyCode" :isRefreshCode="isRefreshCode"></s-identify> </div> </div> </template> <script> import Vue from "vue"; import SIdentify from "./common/SIdentify"; export default { components: { SIdentify }, data() { return { verificationCode: "", identifyCodes: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"], identifyCode: "", isRefreshCode: false, }; }, created() { this.refreshCode(); }, mounted() {}, watch: {}, methods: { refreshCode() { this.identifyCode = ""; this.isRefreshCode = true; //更改状态--SIdentify组件中监听该状态 // 随机排序 if (this.identifyCodes.length) { let tempCodesArray = this.identifyCodes.sort(function() { return Math.random() - 0.5; }); this.identifyCodes = tempCodesArray; } }, getSidentifyCode(data) { this.identifyCode = data; this.isRefreshCode = false; console.log(this.identifyCode, "接收到的code"); } } }; </script> <style lang="scss" scoped> .identify-code { display: inline-block; } } </style>
当用方式②时, SIdentify.vue 组件 可以略去 isRefreshCode的监听判断,改为监听 identifyCodes
代码段为
SIdentify.vue <script> export default { ... watch: { identifyCodes() { this.drawPic(); } //, // isRefreshCode() { // this.drawPic(); // } } }; </script> <style lang="scss" scoped> . . . </style>
smile蓿苜