uni-app 內建canvas生成驗證碼
阿新 • • 發佈:2021-01-25
前言
使用uni-app在開發登入驗證過程中,需用到驗證碼功能。雖說現在大部分使用簡訊驗證或者滑動驗證,但是少部分需求還是有的。
封裝元件的思路如下:
- 生成驗證碼字符集 1~9 且 a~z(自行可排除
1、l
或0,o
容易混淆的字元) - 生成隨機顏色 可通過生成
#0123ab
這種的十六進位制的顏色 - 建立畫布並將上述的驗證碼及顏色帶入畫布中
- 隨機畫n個直線可做干擾項
- 點選驗證碼重新呼叫 達到換驗證碼效果,並賦值到父元件上
子元件程式碼如下:
<template>
<view class="Captcha">
< view v-show="capShow">
<-- 畫布 -->
<canvas
style="width: 202upx; height: 88upx;background:white"
canvas-id="js-captcha"
@tap="tapCaptcha"
></canvas>
</view>
</view>
</template>
< script>
export default {
name: "Captcha",
data() {
// 驗證碼字符集
const arr = [2, 3, 4, 5, 6, 7, 8, 9];
for (var i = 65; i < 122; i++) {
if (i > 90 && i < 97) {
continue;
}
arr.push(String.fromCharCode(i));
}
return {
capValue: "",
capShow: true,
character: arr
};
},
mounted() {
this.creatCanvas();
},
methods: {
// 初始化canvas
creatCanvas() {
let str = "";
this.capValue = "";
// 隨機字元
for (var i = 0; i < 4; i++) {
var a = this.character[
Math.floor(Math.random() * this.character.length)
];
str += a;
this.capValue += a;
}
// 隨機顏色
function setColor() {
var colorValue = "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f";
var colorArray = colorValue.split(",");
var color = "#";
for (var i = 0; i < 6; i++) {
color += colorArray[Math.floor(Math.random() * 16)];
}
return color;
}
// console.log(Math.floor(Math.random() * 8 - 4));
// 建立畫布
var ctx = uni.createCanvasContext("js-captcha");
// 數字字母
ctx.setFontSize(28 + Math.floor(Math.random() * 4 - 2));
ctx.setFillStyle(setColor());
for (let i = 0; i < 4; i++) {
ctx.setFontSize(28 + Math.floor(Math.random() * 4 - 2));
ctx.fillText(str[i], 20 * i + 10, 32);
ctx.setFillStyle(setColor());
// 旋轉隨機在-3到3之間
ctx.rotate((Math.floor(Math.random() * 6 - 3) * Math.PI) / 180);
}
// 直線
// begin path
for (let i = 0; i < 10; i++) {
ctx.beginPath();
ctx.setStrokeStyle(setColor());
// x/-10~110 y/-10~50
ctx.moveTo(
Math.floor(Math.random() * 100) + Math.floor(Math.random() * 20 - 10),
Math.floor(Math.random() * 40) + Math.floor(Math.random() * 20 - 10)
);
ctx.lineTo(
Math.floor(Math.random() * 100) + Math.floor(Math.random() * 20 - 10),
Math.floor(Math.random() * 40) + Math.floor(Math.random() * 20 - 10)
);
ctx.stroke();
}
ctx.draw();
},
// 點選畫布重置初始化方法,達到切換驗證碼效果
tapCaptcha() {
this.capShow = false;
this.$nextTick(() => {
this.capShow = true;
this.creatCanvas();
});
}
},
watch: {
// 通過監聽驗證碼 向父元件傳遞值
capValue: {
handler(newVal) {
this.$emit("captcha", this.capValue);
}
}
}
};
</script>
父元件程式碼如下:
<template>
<view>
<!-- 驗證碼 -->
<Captcha @captcha="captcha" />
</view>
</template>
<script>
import Captcha from "@/components/consult/Captcha";
export default {
components: {
Captcha,
},
data(){
return {
captchaVal: "",
}
},
methods: {
captcha(emit) {
console.log(emit);
this.captchaVal = emit;
},
}
}
</script>
附上效果圖如下:
總結:
封裝該元件遇到的主要問題在於uni-app 畫布的使用,可以多去了解官方的文件。