效果图:
html代码
输入错误三次显示该验证码,isSidentify 为输错次数
<div class="inputYzm vfCode" v-if="isSidentify >= 3"><input placeholder="请输入验证码" v-model="sidentifyMode" /><div @click="refreshCode()" class="vfCodeComponents" title="点击切换验证码"><v-sidentify :identifyCode="identifyCode"></v-sidentify></div>
</div>
定义和方法
data(){return {isSidentify: 0,sidentifyMode: '',identifyCode: '',identifyCodes: ['0','1','2','3'...'a','b','c'...'z']//验证码出现的数字和字母}
}
methods:{//登录submit() {if (this.isSidentify >= 3) {if (!this.sidentifyMode) {this.$message({type: 'warning',duration: '2000',message: '验证码不能为空!'})return}if (this.sidentifyMode.toLowerCase() != this.identifyCode.toLowerCase()) {this.$message({type: 'warning',duration: '2000',message: '验证码错误!'})this.refreshCode()return}}},// 生成随机数randomNum(min, max) {max = max + 1return Math.floor(Math.random() * (max - min) + min)},// 更新验证码refreshCode() {this.identifyCode = ''this.makeCode(this.identifyCodes, 4)// console.log('当前验证码:', this.identifyCode)},// 随机生成验证码字符串makeCode(data, len) {// console.log('data, len:', data, len)for (let i = 0; i < len; i++) {this.identifyCode += this.identifyCodes[this.randomNum(0, this.identifyCodes.length - 1)]}},
}
样式
.vfCode {background: #fff;width: 180px;height: 50px;border-radius: 25px;border: solid 1px #13c2c0;margin-top: 38px;&.inputYzm {background: white url('../img/login-yzm.png') no-repeat 15px center;background-size: 35px 35px;}input {background: none;border: none;outline: none;width: 130px;height: 100%;margin-left: 60px;font-size: 16px;border-radius: 0px 35px 35px 0px;box-shadow: inset 0 0 0 1000px #fff !important;}.vfCodeComponents {position: relative;bottom: 43px;left: 219px;cursor: pointer;}
}
验证码组件 identifyCode ,核心代码
<template><div class="s-canvas"><canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas></div>
</template>
<script>
export default {name: 'SIdentify',props: {identifyCode: {type: String,default: '1234'},fontSizeMin: {type: Number,default: 18},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: 111},contentHeight: {type: Number,default: 38}},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(-30, 30) // 字符旋转角度(不超过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)},drawLine(ctx) {// 绘制干扰线for (let i = 0; i < 8; 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 < 100; 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>
感谢大佬分享,点击 这里