服务器之家:专注于服务器技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - React - React tsx生成随机验证码

React tsx生成随机验证码

2022-03-09 16:08laipengfei19 React

这篇文章主要为大家详细介绍了React tsx生成随机验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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>

好了,效果如下图:

React tsx生成随机验证码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/laipengfei19/article/details/116016325

延伸 · 阅读

精彩推荐
  • ReactReact使用高德地图的实现示例(react-amap)

    React使用高德地图的实现示例(react-amap)

    这篇文章主要介绍了React使用高德地图的实现示例(react-amap),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    yzbyxmx8622022-03-05
  • React一文帮你理解PReact10.5.13源码

    一文帮你理解PReact10.5.13源码

    这篇文章主要介绍了一文帮你理解PReact10.5.13源码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    我的小树林5442022-02-22
  • Reactreact中的虚拟dom和diff算法详解

    react中的虚拟dom和diff算法详解

    这篇文章主要介绍了react中的虚拟dom和diff算法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    家里有只猪4642022-03-05
  • React一看就懂的ReactJs基础入门教程-精华版

    一看就懂的ReactJs基础入门教程-精华版

    现在最热门的前端框架有AngularJS、React、Bootstrap等。自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略...

    雲霏霏9332022-02-22
  • ReactReact中useRef的具体使用

    React中useRef的具体使用

    这篇文章主要介绍了React中useRef的具体使用,它可以用来获取组件实例对象或者是DOM对象,除此之外还有哪些用法,就一起来了解一下...

    Meskjei6392022-02-28
  • ReactReact.cloneElement的使用详解

    React.cloneElement的使用详解

    因为要接手维护一些项目,团队的技术栈最近从 vue 转向 react ,作为一个 react 新手,加上一向喜欢通过源码来学习新的东西,就选择了通过阅读 antd 这个大...

    fullstackbb11292022-02-23
  • React详解react应用中的DOM DIFF算法

    详解react应用中的DOM DIFF算法

    这篇文章主要介绍了react应用中的DOM DIFF算法,帮助大家更好的理解和学习使用react,感兴趣的朋友可以了解下...

    time_w6302022-02-25
  • Reactreact获取input输入框的值的方法示例

    react获取input输入框的值的方法示例

    这篇文章主要介绍了react获取input输入框的值的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友...

    Pinkh8222022-02-24