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