vue2 验证码
StaticVerify.vue
<template>
<canvas ref="canvasRef" class="verify" :width="width" :height="height" @click="drawCode"></canvas>
</template>
<script>
export default {
props: {
// 加减计算最小值
min: {
type: Number,
default: 0
},
// 加减计算最大值
max: {
type: Number,
default: 9
},
// 验证码图片的宽高
width: {
type: Number,
default: 160
},
height: {
type: Number,
default: 60
},
// 验证码的类型
verifyType: {
type: String,
default: 'default',
validator: (val) => {
// default数字和小写字母混合
// cal 两个数加减
return ['default','cal'].includes(val);
}
},
// 字母字符串的长度
strLength: {
type: Number,
default: 5
},
// 背景色
bg: {
type: String,
default: '#ffffff'
}
},
data() {
return {
// 操作符号 只计算加减
operator: [1,-1],
// code集合
codeList: [0,1,2,3,4,5,6,7,8,9,'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'],
// 结果
result: undefined
};
},
mounted() {
this.drawCode();
this.adjustWindow(this.$refs.canvasRef);
},
methods: {
// 绘制验证码
drawCode() {
// 获取对象
let canvas = this.$refs.canvasRef;
// 创建画布环境
let context = canvas.getContext('2d');
context.clearRect(0,0,this.width,this.height);
// 绘制背景
context.fillStyle = this.bg;
// 清空画布
context.fillRect(0,0,this.width,this.height);
// 绘制80个点
for(let i = 0;i < 80;i++) {
this.drawPoint(context);
}
// 绘制内容
context.strokeStyle = this.randColor();
// 文字大小为高的一半,并随即加减-5~10
let fontSize = parseInt(this.height / 2) + this.randomNum(-5,10);
// 字体
context.font = `${fontSize}px 楷体`;
// 文字内容
let textContent = this.createContent();
// 计算文字偏移量
let textX = parseInt((this.width - context.measureText(textContent).width) / 2) ;
// 设置文字旋转
let angle = this.randomNum(-8,8);
context.rotate(Math.PI / 180 * -angle);
context.strokeText(textContent, textX, parseInt(this.height / 1.5));
context.rotate(Math.PI / 180 * angle);
// 向父组件返回结果
this.$emit('get-result',this.result);
return this.result
},
// 绘制点
drawPoint(context) {
// 获取点的随机颜色
context.fillStyle = this.randColor();
context.beginPath();
// 生成随机圆心
let x = this.randomNum(0,this.width);
let y = this.randomNum(0,this.height);
// 生成随机半径
let r = Math.random();
// 生成圆环
context.arc(x,y,r,0,Math.PI * 2,true);
context.closePath();
// 填充圆
context.fill();
},
// 生成绘制内容
createContent() {
let str = '';
// 判断类型
if(this.verifyType == 'default') {
// 绘制文字和数字的组合
for(let i = 0;i < this.strLength;i++) {
let i = this.randomNum(0,35);
str += this.codeList[i] + ' ';
}
this.result = str;
}else{
// 加减
let num1 = this.randomNum(this.min,this.max);
let num2 = this.randomNum(this.min,this.max);
let op = this.operator[this.randomNum(0,1)];
// 计算结果
this.result = num1 + op * num2;
str = num1 + (op > 0 ? ' + ' : ' - ') + num2 + ' = ?';
}
//
return str;
},
// 生成从minNum到maxNum的随机数
randomNum(minNum,maxNum) {
switch(arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1,10);
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum,10);
default:
return 0;
}
},
// 生成随机颜色
randColor() {
let r = this.randomNum(255);
let g = this.randomNum(255);
let b = this.randomNum(255);
return `rgb(${r},${g},${b})`;
},
adjustWindow (dom) {
// 获取屏幕参数
let screen = window.screen;
// 屏幕比例
let screenZoom = screen.width / 1920;
// 窗口比例
let windowZoom = window.innerWidth / window.outerWidth;
// 这里要考虑浏览器是否全屏的
if(screen.width > window.outerWidth) {
// 此时浏览器非全屏
windowZoom = window.outerWidth / screen.width;
}
// 保留3位小数
let zoom = parseFloat((screenZoom * windowZoom).toFixed(3));
// 改变dom的style
dom.style.zoom = zoom;
// 监听窗口的变化
window.addEventListener('resize', () => {
// 屏幕比例
screenZoom = screen.width / 1920;
// 窗口比例
windowZoom = window.innerWidth / window.outerWidth;
// 这里要考虑浏览器是否全屏的
if(screen.width > window.outerWidth) {
// 此时浏览器非全屏
windowZoom = window.outerWidth / screen.width;
}
// 保留三位小数
zoom = parseFloat((screenZoom * windowZoom).toFixed(3));
// 改变dom的style
dom.style.zoom = zoom;
});
}
}
};
</script>
<template>
<div>
<static-verify :width="160" :strLength="4" @get-result="handleResult"></static-verify>
<el-button type="primary" @click="refreshC">刷新</el-button>
<p>接收到的结果: {{ receivedResult }}</p>
</div>
</template>
<script>
import StaticVerify from '../../components/StaticVerify.vue'
export default {
components: { StaticVerify },
data() {
return {
receivedResult: ''
};
},
mounted() {
},
methods: {
handleResult(result) {
// 处理从子组件接收到的结果
this.receivedResult = result;
},
refreshC() {
console.log('refresh')
let result = this.$refs.fromimg.drawCode();
this.receivedResult = result;
}
}
};
</script>