• 售前

  • 售后

热门帖子
入门百科

React tsx生成随机验证码

[复制链接]
用户5592359840 显示全部楼层 发表于 2021-10-26 13:12:09 |阅读模式 打印 上一主题 下一主题
React tsx 天生随机验证码,供各人参考,具体内容如下
最近开发React 利用tsx编写,没有找到什么好的随机天生验证码的插件,自己就手撸了一个,废话不多话,直接上代码。
tsx文件如下:

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

以上就是本文的全部内容,希望对各人的学习有所资助,也希望各人多多支持脚本之家。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作