React tsx 生成随机验证码,供大家参考,具体内容如下
最近开发React 使用tsx编写,没有找到什么好的随机生成验证码的插件,自己就手撸了一个,废话不多话,直接上代码。
tsx文件如下:
React代码片.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
import * as React from "react" ; const size = 4; const verifycode = { width: "32%" , height: "32px" , marginLeft: "5%" , display: "inline-block" , position: "absolute" as "absolute" , top: "0" , right: "0" , } export default class InputVerify extends React.Component<any, any> { constructor(props) { super (props); this .state = { options: { id: "verifycode" , //容器Id canvasId: "verifyCanvas" , //canvas的ID width: "150" , //默认canvas宽度 height: "47" , //默认canvas高度 type: "blend" , //图形验证码默认类型blend:数字字母混合类型、number:纯数字、letter:纯字母 code: "" , numArr: "0,1,2,3,4,5,6,7,8,9" .split( "," ), letterArr: this .getAllLetter(), } } } componentDidMount() { const self = this ; setTimeout(() => { self._init(); self.refresh(); }, 100) this .props.onRef( this ); // 调用父组件传入的函数,把自身赋给父组件 } _init() { let con = document.getElementById( this .state.options.id); let canvas = document.createElement( "canvas" ); this .state.options.width = con.offsetWidth > 0 ? con.offsetWidth : "150" ; this .state.options.height = con.offsetHeight > 0 ? con.offsetHeight : "47" ; canvas.id = this .state.options.canvasId; canvas.width = this .state.options.width; canvas.height = this .state.options.height; canvas.style.cursor = "pointer" ; canvas.innerHTML = "您的浏览器版本不支持canvas" ; con.appendChild(canvas); let parent = this ; canvas.onclick = function () { parent.refresh(); } } refresh() { this .state.options.code = "" ; let canvas : any = document.getElementById( this .state.options.canvasId); let ctx = null ; if (canvas.getContext) { ctx = canvas.getContext( '2d' ); } else { return ; } ctx.clearRect(0, 0, this .state.options.width, this .state.options.height); ctx.textBaseline = "middle" ; ctx.fillStyle = this .randomColor(180, 240); ctx.fillStyle = "rgba(0,0,0,0)" ; //背景色 ctx.fillRect(0, 0, this .state.options.width, this .state.options.height); if ( this .state.options.type == "blend" ) { //判断验证码类型 var txtArr = this .state.options.numArr.concat( this .state.options.letterArr); } else if ( this .state.options.type == "number" ) { var txtArr = this .state.options.numArr; } else { var txtArr = this .state.options.letterArr; } for ( var i = 1; i <= size; i++) { var txt = txtArr[ this .randomNum(0, txtArr.length)]; this .state.options.code += txt; ctx.font = this .randomNum( this .state.options.height / 2, this .state.options.height) + 'px SimHei' ; //随机生成字体大小 ctx.fillStyle = this .randomColor(50, 160); //随机生成字体颜色 // ctx.fillStyle = "rgb(46, 137, 255)";//固定字体颜色 ctx.shadowOffsetX = this .randomNum(-3, 3); ctx.shadowOffsetY = this .randomNum(-3, 3); ctx.shadowBlur = this .randomNum(-3, 3); ctx.shadowColor = "rgba(0, 0, 0, 0.3)" ; var x = this .state.options.width / (size + 1) * i; var y = this .state.options.height / 2; var deg = this .randomNum(-30, 30); /**设置旋转角度和坐标原点**/ 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); } /**绘制干扰线**/ for ( var i = 0; i < 4; i++) { ctx.strokeStyle = this .randomColor(40, 180); ctx.beginPath(); ctx.moveTo( this .randomNum(0, this .state.options.width), this .randomNum(0, this .state.options.height)); ctx.lineTo( this .randomNum(0, this .state.options.width), this .randomNum(0, this .state.options.height)); ctx.stroke(); } } validate(code) { var code = code.toLowerCase(); var v_code = this .state.options.code.toLowerCase(); if (code == v_code) { return true ; } else { this .refresh(); return false ; } } /**生成字母数组**/ getAllLetter() { var letterStr = "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" ; return letterStr.split( "," ); } /**生成一个随机数**/ randomNum(min, max) { return Math.floor(Math.random() * (max - min) + min); } /**生成一个随机色**/ randomColor(min, max) { var r = this .randomNum(min, max); var g = this .randomNum(min, max); var b = this .randomNum(min, max); return "rgb(" + r + "," + g + "," + b + ")" ; } render() { return ( <div id= "verifycode" style={verifycode}></div> ) } } |
这里verifycode的样式自己修改,一般代码片.
1
|
import InputVerify from "../InputVerify" |
这样已经能自动生成验证码了,如何进行验证了,我这里也简单贴出来,这里Form用的antd,一看就懂
代码片.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
export default ($Child: any = {}) => { //Form提交的方法 const onFinish = (values: any) => { if (values.vcode) { console.log($Child.validate(values.vcode)) //调用子组件的方法验证 } }; const onFinishFailed = (errorInfo: any) => { console.log( 'Failed:' , errorInfo); }; return ( <Form {...layout} name= "basic" onFinish={onFinish} onFinishFailed={onFinishFailed} > <Form.Item name= "vcode" rules={[{ required: true , message: '请输入验证码' }]}> <Input size= "large" className= "security-code" placeholder= "请输入验证码" /> </Form.Item> { /* 这里通过onRef来父组件调用子组件的方法 */ } <InputVerify onRef={(ref) => { $Child = ref }}></InputVerify> </Form> ) } |
上面这种写法呢确实是React老的写法,React16.8以后都用hook了,那我也改一下,代码如下:
代码片.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
import * as React from "react" ; const size = 4; const verifycode = { width: "32%" , height: "32px" , marginLeft: "5%" , display: "inline-block" , position: "absolute" as "absolute" , top: "0" , right: "0" , } export default ({cRef}) => { const [code, setCode] = React.useState(Boolean); const [options,setOptions] = React.useState({ id: "verifycode" , //容器Id canvasId: "verifyCanvas" , //canvas的ID width: 150, //默认canvas宽度 height: 47, //默认canvas高度 type: "blend" , //图形验证码默认类型blend:数字字母混合类型、number:纯数字、letter:纯字母 code: "" , numArr: "0,1,2,3,4,5,6,7,8,9" .split( "," ), letterArr: getAllLetter(),}); React.useImperativeHandle(cRef,()=>({ validate : (vcode) => { var vcode = vcode.toLowerCase(); var v_code = options.code.toLowerCase(); if (vcode == v_code) { setCode( true ); } else { refresh(); setCode( false ); } return code; } })); React.useEffect(()=>{ _init(); refresh(); }) function _init() { let con = document.getElementById(options.id); let canvas : any = document.createElement( "canvas" ); options.width = con.offsetWidth > 0 ? con.offsetWidth : 150; options.height = con.offsetHeight > 0 ? con.offsetHeight : 47; canvas.id = options.canvasId; canvas.width = options.width; canvas.height = options.height; canvas.style.cursor = "pointer" ; canvas.innerHTML = "您的浏览器版本不支持canvas" ; con.appendChild(canvas); canvas.onclick = function () { refresh(); } } function refresh() { options.code = "" ; let canvas : any = document.getElementById(options.canvasId); let ctx = null ; if (canvas.getContext) { ctx = canvas.getContext( '2d' ); } else { return ; } ctx.clearRect(0, 0, options.width, options.height); ctx.textBaseline = "middle" ; ctx.fillStyle = randomColor(180, 240); ctx.fillStyle = "rgba(0,0,0,0)" ; //背景色 ctx.fillRect(0, 0, options.width, options.height); if (options.type == "blend" ) { //判断验证码类型 var txtArr = options.numArr.concat(options.letterArr); } else if (options.type == "number" ) { var txtArr = options.numArr; } else { var txtArr = options.letterArr; } for ( var i = 1; i <= size; i++) { var txt = txtArr[randomNum(0, txtArr.length)]; options.code += txt; ctx.font = randomNum(options.height / 2, options.height) + 'px SimHei' ; //随机生成字体大小 ctx.fillStyle = randomColor(50, 160); //随机生成字体颜色 // ctx.fillStyle = "rgb(46, 137, 255)";//固定字体颜色 ctx.shadowOffsetX = randomNum(-3, 3); ctx.shadowOffsetY = randomNum(-3, 3); ctx.shadowBlur = randomNum(-3, 3); ctx.shadowColor = "rgba(0, 0, 0, 0.3)" ; var x = options.width / (size + 1) * i; var y = options.height / 2; var deg = randomNum(-30, 30); /**设置旋转角度和坐标原点**/ 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); } /**绘制干扰线**/ for ( var i = 0; i < 4; i++) { ctx.strokeStyle = randomColor(40, 180); ctx.beginPath(); ctx.moveTo(randomNum(0, options.width), randomNum(0, options.height)); ctx.lineTo(randomNum(0, options.width), randomNum(0, options.height)); ctx.stroke(); } } /**生成字母数组**/ function getAllLetter() { var letterStr = "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" ; return letterStr.split( "," ); } /**生成一个随机数**/ function randomNum(min: any, max: any) { return Math.floor(Math.random() * (max - min) + min); } /**生成一个随机色**/ function randomColor(min, max) { var r = randomNum(min, max); var g = randomNum(min, max); var b = randomNum(min, max); return "rgb(" + r + "," + g + "," + b + ")" ; } return ( <div id= "verifycode" style={verifycode}></div> ) } |
调用也简单,父组件声明一个React.useRef,传给子组件
1
2
3
4
5
6
|
const childRef = React.useRef<any>(); //这里code通过antD的Form表单的onFinish事件获得 //调用子组件方法 childRef.current.validate(code) <InputVerify cRef={childRef}></InputVerify> |
好了,效果如下图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/laipengfei19/article/details/116016325